1

我现在使用 angularjs 已经有几个星期了,但在从 ngModelController 设计 $viewValue 和 $modelValue 功能时,我没有得到 angularjs 设计者的想法。代码示例:

索引.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>

脚本.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

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

我怎样才能做到这一点??

期待您的回答。

4

1 回答 1

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

于 2014-08-19T10:17:27.073 回答