Làm mới Chỉ thị Angular khi thay đổi thông số


75

Tôi có một chỉ thị góc được khởi tạo như vậy:

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

Tôi muốn nó đủ thông minh để làm mới chỉ thị khi $scope.some_propthay đổi, vì điều đó ngụ ý rằng nó sẽ hiển thị nội dung hoàn toàn khác.

Tôi đã thử nghiệm nó như vậy và không có gì xảy ra, chức năng liên kết thậm chí không được gọi khi $scope.some_propthay đổi. Có cách nào để làm cho điều này xảy ra?

Câu trả lời:


97

Hàm liên kết chỉ được gọi một lần, vì vậy nó sẽ không trực tiếp làm những gì bạn mong đợi. Bạn cần sử dụng góc $watchđể xem một biến mô hình.

Đồng hồ này cần được thiết lập trong chức năng liên kết.

Nếu bạn sử dụng phạm vi riêng biệt cho chỉ thị thì phạm vi sẽ là

scope :{typeId:'@' }

Trong chức năng liên kết của bạn, sau đó bạn thêm một chiếc đồng hồ như

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

Nếu bạn không sử dụng phạm vi riêng biệt, hãy xem trên some_prop


7
Tôi đang giải quyết một vấn đề tương tự như OP. Các tài liệu AngularJS ngụ ý rằng việc sử dụng =in scope:sẽ tạo ra một ràng buộc hai chiều, tức là các thay đổi trong phạm vi con truyền đến phạm vi cha và ngược lại - đây không phải là trường hợp? Tôi cần có thể ra lệnh cập nhật chính nó từ bộ điều khiển mẹ.
Eno

@Eno Bạn có tìm ra điều này không? Thật sự làm tôi bối rối!
JMK

@JMK Tôi thấy những bài viết này hữu ích khi đọc: undefinednull.com/2014/02/11/… github.com/angular/angular.js/wiki/Undilities-Scope
Eno

Có hại không khi phạm vi hơn 10000 chỉ thị khởi chạy phạm vi. $ Watch để lắng nghe một bool để làm mới?
Léon Pelletier

Tôi thấy rằng nếu tham số được sử dụng '=', giải pháp trên không làm việc, và tôi đang điều tra về nó ..
Micky

38

Những gì bạn đang cố gắng làm là theo dõi thuộc tính của thuộc tính trong chỉ thị. Bạn có thể xem thuộc tính của các thay đổi thuộc tính bằng cách sử dụng $ quan sát () như sau:

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

    }
  };
});

Hãy nhớ rằng tôi đã sử dụng chức năng 'biên dịch' trong chỉ thị ở đây vì bạn chưa đề cập đến việc bạn có bất kỳ mô hình nào hay không và chức năng này có nhạy cảm về hiệu suất hay không.

Nếu bạn có mô hình, bạn cần thay đổi chức năng ' biên dịch ' thành ' liên kết ' hoặc sử dụng ' bộ điều khiển ' và để theo dõi các thay đổi thuộc tính của mô hình, bạn nên sử dụng $ watch () và sử dụng góc cạnh {{}} dấu ngoặc từ thuộc tính, ví dụ:

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

Và trong chỉ thị:

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

    }
  };
});

1

Tôi hy vọng điều này sẽ giúp tải lại / làm mới chỉ thị trên giá trị từ phạm vi chính

<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>

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

0

Nếu bạn đang sử dụng AngularJS 1.5.3 hoặc mới hơn, Bạn nên cân nhắc chuyển sang các thành phần thay vì chỉ thị. Các lệnh đó hoạt động rất giống với các lệnh nhưng với một số tính năng bổ sung rất hữu ích, chẳng hạn như $ onChanges (changesObj), một trong những móc vòng đời, sẽ được gọi bất cứ khi nào các ràng buộc một chiều được cập nhật.

app.component('conversation ', {
    bindings: {
    type: '@',
    typeId: '='
    },
    controller: function() {
        this.$onChanges = function(changes) {
            // check if your specific property has changed
            // that because $onChanges is fired whenever each property is changed from you parent ctrl
            if(!!changes.typeId){
                refreshYourComponent();
            }
        };
    },
    templateUrl: 'conversation .html'
});

Đây là tài liệu để đi sâu vào các thành phần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.