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

Javascript 使用AngularJS中的指令将对象存储在ngModel中,javascript,angularjs,model,angularjs-directive,angularjs-ng-model,Javascript,Angularjs,Model,Angularjs Directive,Angularjs Ng Model,我和angularjs一起工作了几周,但我没有得到angularjs设计师在设计$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

我和angularjs一起工作了几周,但我没有得到angularjs设计师在设计$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>
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);
  });
});

script.js:

<!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>
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);
  });
});
var-plunkerModule=angular.module('PlunkerApp',[]);
指令('listfield',函数(){
"严格使用",;
var link=函数(范围、元素、属性、ngModelController){
console.log('listfield.link():',作用域);
ngModelController.$parsers.push(函数(值){
log('listfield.model.parser:',值);
返回值?value.join(','):未定义;
});
ngModelController.$formatters.push(函数(值){
log('listfield.model.formatter:',值);
返回值?值。拆分(/,\s*/):未定义;
});
}
返回{
限制:'E',
链接:链接,
要求:'ngModel',
范围:{
ngModel:“=”
},
模板:“”
};
});
plunkerModule.controller('mainController',函数($scope){
$scope.termList=“”;
$scope.$watchCollection('termList',函数(newValue,oldValue){
console.log('mainController.watch.list:',newValue);
});
});
plunker链接:

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

我该怎么做


期待您的回答。

这里的问题是,您的
标记都有一个ngModel,混淆了何时调用哪个。您可以使用指令的
replace:true
选项删除
标记,并仅使用
,如下所示:

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(=)
});
var-plunkerModule=angular.module('PlunkerApp',[]);
指令('listfield',函数(){
"严格使用",;
var link=函数(范围、元素、属性、ngModelController){
console.log('listfield.link():',作用域);
//您的格式化程序和解析器似乎正好相反
//格式化程序转换模型->视图
//而解析器转换视图->模型
ngModelController.$formatters.push(函数(值){
log('listfield.model.formatter:',值);
返回值?value.join(','):未定义;
});
ngModelController.$parsers.push(函数(值){
log('listfield.model.parser:',值);
返回值?值。拆分(/,\s*/):未定义;
});
}
返回{
限制:'E',
链接:链接,
要求:'ngModel',
replace:true,//删除标记
范围:{
型号:'='
},
模板:“”
};
});
plunkerModule.controller('mainController',函数($scope,$timeout){
$scope.termList=[1,2,3]
$scope.$watchCollection('termList',函数(newValue,oldValue){
console.log('mainController.watch.list:',newValue);
});
$timeout(函数changeTermList(){$scope.termList=[4,5,6]},2000)
//这是为了演示通过隔离作用域(=)使用的绑定
});
以及相关的HTML:

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


演示:

有趣的是,在该代码段中似乎创建了两个NGModelController,第二个(没有格式化程序/解析器)在更新模型值时被调用。这意味着必须删除输入“ng model”属性,并且我必须处理所有事件(keydown、blur、watch on model)我自己和angularjs对我没有帮助=(很好!我的新发现是ngModelController被注入,尽管没有指定ng模型..因此ngModelController是该指令的一个独立实例?我尝试对模板中的两个输入字段使用相同的模型,如下所示:这可以工作,但会删除错误消息:“找不到指令‘listfield’所需的控制器‘ngModel’。您对此有何想法?
require
在同一元素(
)或其父元素上查找指令‘ng model’——因为没有这样的指令,所以会出现该错误。但是当您使用replace时,根本没有
元素。谢谢=)是否有方法将ng模型绑定到非第一个html元素?例如:“”。