Angular Обновление директивы при изменении параметра

У меня есть директива angular, которая инициализируется следующим образом:

<conversation style="height:300px" type="convo" type-id="{{some_prop}}"></conversation>

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

Я тестировал его как есть, и ничего не происходит, функция связывания даже не вызывается при изменении $scope.some_prop. Есть ли способ сделать это?

Ответ 1

Функция Link только получает вызов один раз, поэтому он не будет делать то, что вы ожидаете. Вам нужно использовать angular $watch для просмотра переменной модели.

Эти часы должны быть настроены в функции связи.

Если вы используете изолированную область для директивы, то область будет

scope :{typeId:'@' }

В вашей функции ссылок вы добавляете такие часы, как

link: function(scope, element, attrs) {
    scope.$watch("typeId",function(newValue,oldValue) {
        //This gets called when data changes.
    });
 }

Если вы не используете выделенную область использования, смотрите на some_prop

Ответ 2

То, что вы пытаетесь сделать, - это контролировать свойство атрибута в директиве. Вы можете посмотреть свойство изменений атрибутов с помощью $observ() следующим образом:

angular.module('myApp').directive('conversation', function() {
  return {
    restrict: 'E',
    replace: true,
    compile: function(tElement, attr) {
      attr.$observe('typeId', function(data) {
            console.log("Updated data ", data);
      }, true);

    }
  };
});

Имейте в виду, что я использовал функцию компиляции в директиве здесь, потому что вы не упомянули, есть ли у вас какие-либо модели и зависит ли это от производительности.

Если у вас есть модели, вам нужно изменить функцию "компиляция" на "ссылку" или использовать "контроллер" и контролировать свойство изменений модели, вы должны использовать $watch(), и возьмите из angular {{}} скобки из свойства, например:

<conversation style="height:300px" type="convo" type-id="some_prop"></conversation>

И в директиве:

angular.module('myApp').directive('conversation', function() {
  return {
    scope: {
      typeId: '=',
    },
    link: function(scope, elm, attr) {

      scope.$watch('typeId', function(newValue, oldValue) {
          if (newValue !== oldValue) {
            // You actions here
            console.log("I got the new value! ", newValue);
          }
      }, true);

    }
  };
});

Ответ 3

angular.module('app').directive('conversation', function() {
    return {
        restrict: 'E',
        link: function ($scope, $elm, $attr) {
            $scope.$watch("some_prop", function (newValue, oldValue) {
                  var typeId = $attr.type-id;
                  // Your logic.
            });
        }
    };
}

Ответ 4

Я надеюсь, что это поможет перезагрузить/обновить директиву по значению из родительской области

<html>

        <head>
            <!-- version 1.4.5 -->
            <script src="angular.js"></script>
        </head>

        <body ng-app="app" ng-controller="Ctrl">

            <my-test reload-on="update"></my-test><br>
            <button ng-click="update = update+1;">update {{update}}</button>
        </body>
        <script>
            var app = angular.module('app', [])
            app.controller('Ctrl', function($scope) {

                $scope.update = 0;
            });
            app.directive('myTest', function() {
                return {
                    restrict: 'AE',
                    scope: {
                        reloadOn: '='
                    },
                    controller: function($scope) {
                        $scope.$watch('reloadOn', function(newVal, oldVal) {
                            //  all directive code here
                            console.log("Reloaded successfully......" + $scope.reloadOn);
                        });
                    },
                    template: '<span>  {{reloadOn}} </span>'
                }
            });
        </script>


   </html>