J'ai une configuration de montre contre le modèle d'un menu déroulant ui-select2 (à partir de ui-bootstrap). La montre se déclenche à la charge, mais pas sur les changements de données et je ne comprends pas pourquoi.
Ce n'est pas le problème habituel de ne pas appliquer le changement de modèle ni d'utiliser le troisième paramètre pour la comparaison d'égalité (du moins d'après mon code).
Que dois-je faire pour l'obtenir?
J'ai réparé des trucs.
http://plnkr.co/edit/5Zaln7QT2gETVcGiMdoW?p=preview
Le JS
var myMod = angular.module("myApp",[]).controller("MainController", function($scope){
$scope.myModel = {selectedId:null};
}).controller("DetailController",function($scope){
$scope.items = [1,2,3,4];
$scope.watchHitCount = 0;
$scope.$watch('myModel.selectedId', function(newVal, oldVal){
console.log(newVal + " " + oldVal);
$scope.watchHitCount++;
},true);
});
L'index.html
<body ng-app="myApp">
<div ng-controller="MainController">
<ng-include src="'detail.html'" ng-controller="DetailController"></ng-include>
</div>
</body>
Le detail.html
<pre>watch hit: {{watchHitCount}}</pre>
<pre>selected value: {{myModel.selectedId}}</pre>
<select ng-model="myModel.selectedId" ui-select2="">
<option></option>
<option ng-repeat="item in items" value="{{item}}">{{item}}</option>
</select>
Il se plaignait de ne pas trouver le contrôleur, donc je l'ai configuré comme je le ferais normalement avec une application nommée et un module déclaré avec des contrôleurs définis.
J'ai également ajouté un objet pour conserver la valeur dans votre modèle. Il est déconseillé d'utiliser l'objet $ scope en tant que modèle. à un objet qui est votre modèle.
Essayez de passer true
comme troisième argument à .$watch()
$rootScope.Scope
documentation
$watch(watchExpression, listener, objectEquality)
objectEquality (optionnel) - {boolean =} - Compare l'objet pour l'égalité plutôt que pour la référence.
Il existe un correctif simple pour cela, utiliser watch avec un objet complexe au lieu d'une simple variable
Par exemple (NE PAS UTILISER)
$scope.selectedType=1;//default
$scope.$watch(
function () {
return $scope.selectedType;
},
function (newValue, oldValue) {
if (!angular.equals(oldValue, newValue)) {
$scope.DoWork();
}
},
true);
Mais utiliser ci-dessous
$scope.selecteditem={selectedType:1};
$scope.$watch(
function () {
return $scope.selecteditem.selectedType;
},
function (newValue, oldValue) {
if (!angular.equals(oldValue, newValue)) {
$scope.DoWork();
}
},
true);
notez que "slectedTypes" dans le deuxième exemple situé à l'intérieur de l'objet, pas seulement une variable de portée. cela fonctionnera même dans les anciennes Angular versions.
Si vous utilisez l'approche controller-as, certaines lectures pourraient suggérer une syntaxe comme celle-ci:
var myController = {
myValue: 1
};
$scope.$watch('$ctrl.myValue', function () {
...
}, true);
Plutôt que d’envelopper le champ dans une fonction comme celle-ci:
var myController = {
myValue: 1
};
$scope.$watch(function () {
return myController.myValue;
}, function () {
...
}, true);