The “with” binding of KnockoutJS in AngularJS?

后端 未结 3 1144
小鲜肉
小鲜肉 2021-01-01 16:22

I have just switched from KnockoutJS to AngularJS and I am not able to find the KnockoutJS\'s \"with\" data-bind in AngularJS.

Here is the piece of code in KnockoutJ

3条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-01 16:51

    Create a custom directive that loops through the source object and creates corresponding properties on the directive's scope that are getter/setter references to the source object.

    Check out this plunker.

    directive module:

    angular.module('koWith', [])
      .directive('koWith', function () {
        return {
          controller: function ($scope, $attrs) {
            var withObj = $scope.$parent[$attrs.ngWith];
    
            function getter(prop) {
              return this[prop];
            }
            function setter(val, prop) {
              this[prop] = val;
            }
    
            for (var prop in withObj) {
              if (withObj.hasOwnProperty(prop)) {
                Object.defineProperty($scope, prop, {
                  enumerable: true,
                  configurable: true,
                  get: getter.bind(withObj, prop),
                  set: setter.bind(withObj, prop)
                });
              }
            }
          },
          restrict: 'A',
          scope: true
        };
      });
    

    app module:

    angular.module('myApp', [])
      .controller('myController', function ($scope) {
        $scope.customer = {
          name: "Timmeh",
          address: {
            address1: "12 S Street",
            address2: "",
            city: "South Park",
            state: "CO",
            zipCode: "80440"
          }
        };
      });
    

    html:

    {{name}}

    {{address1}}
    {{address2}}
    {{city}}, {{state}} {{zipCode}}

    Explanation

    In KnockoutJS, bindings keep the bindingContext and data separated so creating the with binding is trivial since it only needs to create a new child bindingContext from the current one and use the with object as its data value.

    In AngularJS, a directive's scope is basically the bindingContext and data object rolled into one. When a new scope is created, in order to get the with-like behavior, the properties of the with object have to be referenced onto the newly created scope object.

提交回复
热议问题