【问题标题】:How to bind to ng-model inside a directive that has no scope?如何在没有范围的指令内绑定到 ng-model?
【发布时间】:2016-06-08 16:49:08
【问题描述】:

我想创建一个指令来包装表单元素(输入、文本区域、选择等)并绑定到 ng-model。

用法如下:

<div ng-controller="formController">
    <field 
           type="text" 
           ng-model="model.CellPhoneNumber" 
           label="Cell phone" 
           mini-help="Sample: 123412341234" 
           required="please give us your number" 
           numeric 
           cellPhone="cell phone number is invalid" />
    <div>{{ model.CellPhoneNumber }}</div>
</div>
<script>
    app.cp.register('formController', ['$scope', function ($scope) {

    }]);
</script>

这是我的指令:

app.directive('field', function () {
        return {
            restrict: 'E',
            replace: 'true',
            scope: false,
            require: 'ngModel',
            template: '<div class="field">' +
                            '<label ng-if="label">{{ label }}</label>' +
                            '<input type="text" ng-if="type == \'text\'" required ng-model="ngModel" />' +
                            '<span class="mini help" ng-if="miniHelp">{{ miniHelp }}</span>' +
                            '<span class="messages">' +
                                '<span class="error message" ng-message="required" ng-if="requried">{{ required }}</span>' +
                            '</span>' +
                      '</div>',
            link: function (scope, element, attributes, ngModel) {
                scope.label = attributes.label;
                scope.miniHelp = attributes.miniHelp;
                scope.type = attributes.type;
                scope.required = attributes.required;
            }
        };
    });

但是,它不起作用。我被困在绑定 ng-model 上。我知道我可以通过范围:{} 切换到子范围,并且一切正常。但我需要范围:false。

这里有一个很好的例子来说明如何做到这一点。但我找不到范围为 false 的样本。

Dynamic ng-model binding inside a directive

【问题讨论】:

  • 您也必须发布您的控制器和应用代码,才能正确回答

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

您非常接近所需的解决方案。 link 函数的第四个参数是ngModelController,它与ngModel 不同。您的问题是您将其用作计划ngModel。您需要做的只是几个小改动。

首先,您需要将ngModelController 绑定到您的scope。然后,您绑定$viewValue,而不是ng-model="ngModel",如下所示:ng-model="ngModel.$viewValue"。最后,您需要创建一个监视以允许您的指令field 更改ngModel 的值,否则它将是一个方向的。

这是工作代码:

angular
  .module('myApp', [])
  .directive('field', function() {
    return {
      restrict: 'E',
      replace: 'true',
      scope: false,
      require: 'ngModel',
      template: '<div class="field">' +
        '<label ng-if="label">{{ label }}</label>' +
        '<input type="text" ng-if="type == \'text\'" required ng-model="ngModel.$viewValue" />' +
        '<span class="mini help" ng-if="miniHelp">{{ miniHelp }}</span>' +
        '<span class="messages">' +
        '<span class="error message" ng-message="required" ng-if="requried">{{ required }}</span>' +
        '</span>' +
        '</div>',
      link: function(scope, element, attributes, ngModel) {
        scope.label = attributes.label;
        scope.miniHelp = attributes.miniHelp;
        scope.type = attributes.type;
        scope.required = attributes.required;

        scope.ngModel = ngModel;
        scope.$watch(function() {
          return ngModel.$viewValue;
        }, function(newValue) {
          ngModel.$setViewValue(newValue);
          ngModel.$render();
        });
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>

<div ng-app="myApp" ng-init="myModel = 'qwe'">
  <field type="text" ng-model="myModel" label="Cell phone" mini-help="Sample: 123412341234" required="please give us your number" numeric cellPhone="cell phone number is invalid"></field>

  <input type="text" ng-model="myModel">
  <p>{{ myModel }}</p>
</div>

【讨论】:

    【解决方案2】:

    你总是可以在你的角度指令中使用属性

    【讨论】:

      猜你喜欢
      • 2014-08-07
      • 1970-01-01
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 2015-12-20
      • 2018-08-23
      相关资源
      最近更新 更多