角度ng模型动态getter和setter

时间:2015-04-15 10:14:33

标签: javascript angularjs angular-ngmodel

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

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

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

注意:我的控制器中的$ scope上没有定义balance。因为我们处理的是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可以这样吗?

7 个答案:

答案 0 :(得分:3)

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

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

  

编辑:由@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 />

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

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

如果您需要更新外部服务,请在控制器中实施更改(变量)的方法。

答案 5 :(得分:0)

ES5救援的对象属性:

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

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

答案 6 :(得分:0)

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

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