1

私は数週間 angularjs を使用していますが、 ngModelController から $viewValue および $modelValue 機能を設計するときに angularjs デザイナーが考えたことがわかりませ。コード例:

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

プランカーリンク: 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 に答える