簡體   English   中英

AngularJS自定義指令雙向綁定

[英]AngularJS Custom Directive Two Way Binding

如果我有一個沒有模板的AngularJS指令,並且我希望它在當前作用域上設置屬性,那么最好的方法是什么?

例如,一個計算按鈕點擊次數的指令:

<button twoway="counter">Click Me</button>
<p>Click Count: {{ counter }}</p>

使用指令將點擊計數分配給雙向屬性中的表達式:

.directive('twoway', [
'$parse',
  function($parse) {
    return {
      scope: false,
      link: function(scope, elem, attrs) {
        elem.on('click', function() {
          var current = scope.$eval(attrs.twoway) || 0;
          $parse(attrs.twoway).assign(scope, ++current);
          scope.$apply();
        });
      }
    };
  }
])

有一個更好的方法嗎? 從我所讀到的,一個孤立的范圍將是矯枉過正,但我​​需要一個兒童范圍? 除了使用$parse之外,還有一種更簡潔的方法可以回寫指令屬性中定義的范圍變量。 我覺得我讓這個太難了。

Full Plunker 在這里

為什么隔離范圍過大? 它對於這種事情非常有用:

  scope: {
     "twoway": "=" // two way binding
  },

對於這個問題,這是一個非常慣用的角度解決方案,所以這就是我堅持的。

我很驚訝沒有人提到ng-model ,這是進行雙數據綁定的默認指令。 也許它不是那么出名,但鏈接功能有第四個參數:

angular.module('directive-binding', [])
  .directive('twoway', 
      function() {
        return {
          require: '?ngModel',
          link: function(scope, elem, attrs, ngModel) {
            elem.on('click', function() {
              var counter = ngModel.$viewValue ? ngModel.$viewValue : 0
              ngModel.$setViewValue(++counter);
              scope.$apply();
            });
          }
        };
      }
    );

在你的觀點

<button twoway ng-model="counter">Click Me</button>
<p>Click Count: {{ counter }}</p>

第四個參數是ngModelController的API,它具有許多用於處理(例如解析和格式化)以及在指令和范圍之間共享數據的用途。

這是更新的Plunker

你可以在不使用$parse情況下簡化它

angular.module('directive-binding', []).directive('twoway', [function () {
    return {
        scope: false,
        link: function (scope, elem, attrs) {
            elem.on('click', function () {
                scope[attrs.twoway] = scope[attrs.twoway] == null ? 1 : scope[attrs.twoway] + 1;
                scope.$apply();
            });
        }
    };
}]);

應用雙向綁定的一種好方法是使用指令組件。 這是我的解決方案。 它允許使用ng-repeat和可擴展數據綁定。

查看Plunker

HTML

<body ng-controller='MainCtrl'>  
    Data: {{data}}
    <hr>
    <mydirective name='data[0]'></mydirective>
    <hr>
    <mydirective name='data[1]'></mydirective>
</body>

調節器

app.controller('MainCtrl', function($scope) {
  $scope.data = [];
  $scope.data[0] = 'Marco';
  $scope.data[1] = 'Billy';
});

指示

app.directive("mydirective", function(){
    return {
        restrict: "EA",
        scope: {name: '='},
        template: "<div>Your name is : {{name}}</div>"+
        "Change your name : <input type='text' ng-model='name' />"
    };
});

在計數器的情況下,可以使用相同的方法完成。

將模板更改為:

<button twoway bind="counter">Click Me</button>
<p>Click Count: {{ counter.val }}</p>

並指示:

.directive('twoway',
    function() {
        return {
            scope: {
                localValue: '=?bind'
            },
            link: function(scope, elem, attrs) {
                scope.localValue = {
                    val: 0
                };
                elem.on('click', function() {
                    scope.localValue.val = scope.localValue.val + 1;
                    scope.$apply();
                });
            }
        };
    }
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM