【问题标题】:Angular ng-model dynamic getters and settersAngular ng-model 动态 getter 和 setter
【发布时间】:2015-04-15 10:14:32
【问题描述】:

我想将 ng-model 与外部模型服务一起使用。该模型有两种方法:getValue(variable) 和 setValue(variable)。

所以在我的 html 中我希望能够做到:

<input type="text" ng-model="balance">

注意:余额未在我的控制器中的 $scope 上定义。而且因为我们要处理超过 4000 个不同的变量,所以我不想在 $scope 上定义它们。

然后在更改时必须调用模型的 setValue() 方法。所以在我的控制器中,我想有类似的东西:

$catchAllGetter = function(variable) { // e.g. variable = 'balance'
     var value = Model.getValue(variable);
     return value;
}

$catchAllSetter = function(variable, value) { // called on change
     Model.setValue(variable, value);
}

使用 Angular 可以实现这样的事情吗?

【问题讨论】:

标签: javascript angularjs angular-ngmodel


【解决方案1】:

我的方法类似于@Dan Prince,但实现有点不同

创建一个接受模型变量名称的指令,然后将模型服务注入指令本身以执行获取和设置。

Edit : 由@Werlang 指定,编写一个替换的属性 ngModel 将避免您使用验证、格式化等功能, debounced update, ng-change 等等。所以不要写一个替换, 我们将改为连接一个补充属性

    app.directive('dynamicInput', function() {
      return {
        restrict: 'A',
        link: function(scope, el, attr) {
              scope.variableName = angular.copy(attr.ngModel); // Saving the variable name

              scope[attr.ngModel] = (attr.ngModel + '_1'); // Setting a dummy value in the scope variable.
              // In your case it will look something like scope[attr.ngModel] = Model.getValue(attr.ngModel);

                scope.$watch(attr.ngModel, function(newValue, oldValue) {

                  console.log(scope.variableName + " ==> " + newValue);

                  //Model.setValue(scope.variableName, newValue);

              });

        }
      };
    })

然后在你的 HTML 中:

    <input ng-model='balance' dynamic-input />

【讨论】:

  • 这样你就可以释放 ng-model 的所有内置功能,例如验证、格式化、去抖动更新、ng-change 等
  • @TechMa9iac 感谢您的编辑,看起来是一个不错的解决方案!我今天试试看。
【解决方案2】:

您可以创建一个实现此行为的新指令。

<input model-getter='getFn()' model-setter='setFn($value)' />

这很容易实现:

app.directive('modelGetter', function() {
  return {
    restrict: 'A',
    scope: {
      get: '&modelGetter',
      set: '&modelSetter'
    },
    link: function(scope, element) {
      element.val(scope.get());
      element.on('change', function() {
        var val = element.val();
        scope.set({ $value: val });
      });
    }
  };
})

【讨论】:

  • 这样你就可以释放 ng-model 的所有内置功能,例如验证、格式化、去抖动更新、ng-change 等
【解决方案3】:

看看example,我为你创建的。希望我的理解正确

$scope.$watch('variables', function(newValue) {
  console.log("triggers on variables change");
  angular.forEach(newValue, function(value, key) {
    Model.setValue(key, value);
  });  
}, true);

【讨论】:

    【解决方案4】:

    ngModel 支持 getter 和 setter。以下是它的工作原理:

    <input ng-model="balance" ng-model-options="{ getterSetter: true }">
    

    如果 balance 是 getter/setter 函数,则此方法有效:

    $scope.balance(100);      // sets 100
    var b = $scope.balance(); // returns 100
    

    您不需要在作用域上公开每个变量 - 您可以只公开您在示例中使用的 Model 服务:

    $scope.Model = Model;
    

    然后,在视图中,绑定到您需要的任何属性:

    <input ng-model="Model.balance" ng-model-options="{ getterSetter: true }">
    

    【讨论】:

      【解决方案5】:

      将所有变量放在一个对象数组中:

      [
        {key: "Variable 1", value: 1, kind: "number"},
        {key: "Variable 2", value: "some text", kind: "text"},
        {key: "Variable 3", value: new Date(), kind: "date"}
      ]
      

      那么在你看来,你应该在 ng-repeat 的帮助下创建它们:

      <div ng-repeat="variable in myVariables">
          <input type="{{variable.kind}}" ng-model="variable.value" ng-change="changed(variable)">
      </div>
      

      如果您需要更新外部服务,请在控制器中实现方法 changed(variable)。

      【讨论】:

        【解决方案6】:

        ES5 对象属性的救援:

        Object.defineProperty($scope, 'balance', {
          enumberable: true,
          get: function () {
            // -- call your getter here
          },
          set: function (val) {
            // -- call the setter here
          }
        });
        

        这是原生 Javascript,所以它不会比这更快。

        【讨论】:

          【解决方案7】:

          您可以动态评估您的模型函数,例如

          <input type="text" ng-model="myModel(var)">
          

          在控制器中:

          $scope.myModel = function(var) {
            return function(newValue) {
               // this is a regular model function but you can use 'var' here
               ...
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-03-11
            • 1970-01-01
            • 2019-12-14
            • 2017-12-07
            • 1970-01-01
            • 2014-10-30
            • 2015-12-23
            • 2015-10-28
            • 2015-07-05
            相关资源
            最近更新 更多