使用指令将对象存储在ngModel中

时间:2014-08-19 09:37:43

标签: javascript angularjs model angularjs-directive angularjs-ng-model

我现在正在使用angularjs几周,而且我没有得到angularjs设计师在设计ngModelController中的$ viewValue和$ modelValue功能时的想法。代码示例:

的index.html:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.18/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="PlunkerApp" ng-controller="mainController">
    <listfield ng-model="termList"></listfield>
  </body>

</html>

的script.js:

var plunkerModule = angular.module('PlunkerApp', []);

plunkerModule.directive('listfield', function() {
  'use strict';
  var link = function(scope, element, attrs, ngModelController) {
    console.log('listfield.link():', scope);
    ngModelController.$parsers.push(function(value) {
      console.log('listfield.model.parser:', value);
      return value ? value.join(', ') : undefined;

    });
    ngModelController.$formatters.push(function(value) {
      console.log('listfield.model.formatter:', value);
      return value ? value.split(/,\s*/) : undefined;
    });
  }
  return {
    restrict: 'E',
    link: link,
    require: 'ngModel',
    scope: {
      ngModel: '='
    },
    template: '<input type="text" ng-model="ngModel">'
  };
});

plunkerModule.controller('mainController', function($scope) {
  $scope.termList = "";
  $scope.$watchCollection('termList', function(newValue, oldValue) {
    console.log('mainController.watch.list:', newValue);
  });
});

plunker链接: http://plnkr.co/edit/T5a8zEQuRyYWnpsZZV9W?p=preview

所以在这个应用程序中,指令输入元素的值被写入全局范围,工作正常!我的问题是,我对“原始”字符串值不感兴趣,我想要格式化程序生成的数组,但输入元素仍应显示字符串值。

我该怎么做?

期待您的回答。

1 个答案:

答案 0 :(得分:1)

这里的问题是,您的<input><listfield>标记都有一个ngModel,会混淆哪一个被调用。您可以使用指令的replace: true选项删除<listfield>代码,并仅使用<input>,例如:

var plunkerModule = angular.module('PlunkerApp', []);

plunkerModule.directive('listfield', function() {
  'use strict';
  var link = function(scope, element, attrs, ngModelController) {
    console.log('listfield.link():', scope);
    // Your formatters and parsers seemed to be the other way around
    // The formatter transforms Model -> View
    // Whereas the parser transforms View -> Model
    ngModelController.$formatters.push(function(value) {
      console.log('listfield.model.formatter:', value);
      return value ? value.join(', ') : undefined;

    });
    ngModelController.$parsers.push(function(value) {
      console.log('listfield.model.parser:', value);
      return value ? value.split(/,\s*/) : undefined;
    });
  }
  return {
    restrict: 'E',
    link: link,
    require: 'ngModel',
    replace: true, // Removes the <listfield> tag
    scope: {
      model: '='
    },
    template: '<input type="text" ng-model="model">'
  };
});

plunkerModule.controller('mainController', function($scope, $timeout) {
  $scope.termList = [1,2,3]
  $scope.$watchCollection('termList', function(newValue, oldValue) {
    console.log('mainController.watch.list:', newValue);
  });
  $timeout(function changeTermList() { $scope.termList = [4,5,6]}, 2000)
  // This is to demonstrate the binding used via the isolate scope(=)
});

相关的HTML:

  <body ng-app="PlunkerApp" ng-controller="mainController">
    <listfield model="termList"></listfield>
  </body>

演示:http://plnkr.co/edit/G0tlC9qhW8AHa58yVSgj?p=preview