Подтвердить что ты не робот

$ часы не стреляют в изменение данных

У меня есть установка часов против модели выпадающего меню ui-select2 (из ui-bootstrap). Часы срабатывают при загрузке, но не при изменении данных, и я не могу понять, почему.

Это не обычная проблема, если не применить приложение к изменению модели или не использовать третий параметр для сравнения равенства (по крайней мере, из моего кода).

Что мне нужно сделать, чтобы его запустить?

Вот демон, демонстрирующий проблему.

4b9b3361

Ответ 1

Я исправил некоторые вещи.

http://plnkr.co/edit/5Zaln7QT2gETVcGiMdoW?p=preview

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);
});

index.html

  <body ng-app="myApp">
    <div ng-controller="MainController">
      <ng-include src="'detail.html'" ng-controller="DetailController"></ng-include>
    </div>
  </body>

Детали .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>

Он жаловался на то, что не нашел контроллер, поэтому я настроил его так, как обычно, с именем ng-app и объявленным модулем, на котором определены контроллеры.

Я также добавил объект для хранения значения в вашей модели. Плохая практика использования объекта $scope в качестве модели, вместо этого ваша область должна ссылаться на объект, который является вашей моделью.

Ответ 2

Попробуйте передать true в качестве третьего аргумента в .$watch()

$rootScope.Scope документация

$watch(watchExpression, listener, objectEquality)

objectEquality (необязательно) - {boolean =} - Сравнить объект для равенства, а не для ссылки.

Ответ 3

Для этого есть простое решение: использовать часы со сложным объектом вместо простой переменной

Например (DON "T USE)

$scope.selectedType=1;//default
$scope.$watch(
            function () {
                return $scope.selectedType;
            },
            function (newValue, oldValue) {
                if (!angular.equals(oldValue, newValue)) {
                    $scope.DoWork();
                }
            },
            true);

Но используйте ниже

$scope.selecteditem={selectedType:1};
$scope.$watch(
            function () {
                return $scope.selecteditem.selectedType;
            },
            function (newValue, oldValue) {
                if (!angular.equals(oldValue, newValue)) {
                    $scope.DoWork();
                }
            },
            true);

обратите внимание, что "slectedTypes" во втором примере находится внутри объекта, а не только переменная области. это будет работать даже в старых версиях Angular.

Ответ 4

Если вы используете контроллер - как подход, некоторые чтения могут предложить такой синтаксис, как это:

var myController = {
    myValue: 1
};
$scope.$watch('$ctrl.myValue', function () {
    ...
}, true);

Вместо этого просто оберните поле в функцию, подобную этой:

var myController = {
    myValue: 1
};
$scope.$watch(function () {
    return myController.myValue;
}, function () {
    ...
}, true);