从控制器使用ngModel setViewValue

时间:2015-08-17 12:55:23

标签: javascript angularjs angular-ngmodel

我将一个值数组绑定到许多输入元素。输入元素有指令,设置$ parsers,$ formatters和$ validators。控制器不应该关心从viewValue到modelValue的管道。

观点:

  <ul>
    <li ng-repeat="value in main.values">
      <input ng-model="value.v" twice /> {{value.v}}
    </li>
  </ul>

控制器/指令:

function MainController($scope) {
  this.values = [
    {v: 1}, {v: 2}, {v: 3}
  ];  
}

function twice() {
  return {
    require: 'ngModel',
    link: function(scope, elem, attr, ngModel) {
      ngModel.$formatters.push(function(x) { return 2 * x });
      ngModel.$parsers.push(function(x) { return 0.5 * x });
    }
  }  
}

我想实现一份副本&amp;粘贴功能。应从剪贴板数据覆盖所有输入元素中的值。因此,控制器实现一个解析剪贴板数据并为每个输入元素设置值的函数。剪贴板中的值为视图值。由于控制器不知道如何从这些视图值计算模型值,因此必须使用&#39; $解析器&#39;来自&#39; ngModelController&#39;的管道。如何实现MainController.paste()来设置每个输入元素的视图值?

修改

我目前使用list元素的指令解决了实际问题(请参阅注释)。 http://plnkr.co/edit/9c2q2X?p=preview

function pasteValues() {
  return {
    link: function(scope, elem, attr, ngModel) {
      elem.on('paste', function($event) {
        var data = $event.clipboardData || window.clipboardData;
        var text = data.getData('Text');
        var values = text.split(' ');

        var inputs = elem.find('input');
        if (values.length === inputs.length) {
          for(var i = 0, e = values.length; i != e; ++i) {
            var input = inputs[i];
            var ngModel = angular.element(input).controller('ngModel');
            ngModel.$setViewValue(values[i]);
            input.value = values[i];
          }
          $event.preventDefault();
        }
      })
    }
  }  
}

1 个答案:

答案 0 :(得分:1)

我发现了两种可能的解决方案(同时写下问题:-))。 http://plnkr.co/edit/ZNfYKTvSf6coGsohRlot?p=preview

1

第一种不是真正的角度方式,因为控制器必须知道DOM结构。但它很直接,不需要额外的装订和手表。要设置视图值,它使用WSGISocketPrefix /var/run/apache2/wsgi <VirtualHost *:8080> ServerAdmin webmaster@dummy-host.example.com ServerName meinserver.xx WSGIDaemonProcess webvirtmgr display-name=%{GROUP} python-path=/var/www/webvirtmgr WSGIProcessGroup webvirtmgr WSGIScriptAlias / /var/www/webvirtmgr/webvirtmgr/wsgi.py Alias /static /var/www/webvirtmgr/webvirtmgr/static/ Alias /media /var/www/webvirtmgr/webvirtmgr/media/ <Directory /var/www/webvirtmgr/webvirtmgr> <Files wsgi.py> Order deny,allow Allow from all </Files> </Directory> CustomLog ${APACHE_LOG_DIR}/webvirtmgr-access_log common ErrorLog ${APACHE_LOG_DIR}/webvirtmgr-error_log </VirtualHost> 方法为每个输入元素检索ngModelController。

angular.element.controller()

2

第二种解决方案更多是角度方式,并使用了一个addtional指令,可以对粘贴数据进行分析。

function MainController($scope) {
  this.paste = function() {
    var value = this.pasteValue;
    var inputs = angular.element(document.getElementById('values')).find('input');
    angular.forEach(inputs, function(input) {
      var ngModel = angular.element(input).controller('ngModel');
      ngModel.$setViewValue(value);
      input.value = value;
    });
  };
}

观点:

function setView() {
  return {
    require: 'ngModel',
    scope: {
      setView : '='
    },
    link: function(scope, elem, attr, ngModel) {
      scope.$watch('setView', function(newValue) {
        if (angular.isDefined(newValue)) {
          elem.val(newValue);
          ngModel.$setViewValue(newValue);
        }
      })
    }

  }  
}

function MainController($scope) {
  this.paste = function() {
    var value = this.pasteValue;
    this.values.forEach(function(v) { v.i = value });
  };
}