angularJS为内部transclude元素设置ngModel attr

时间:2016-02-10 14:00:08

标签: javascript jquery angularjs angularjs-directive angularjs-ng-transclude

我想将RectBivariateSpline属性设置为任何被转换为derective的元素。

我使用x:`

ngModel

然后在slot transcludes方法中,我使用jquery将 transclude: { 'editor': 'editorControl' },` 的属性添加到link的子级。

问题是尽管该属性被添加到DOM ng-model没有绑定到组件(当我在输入中更改值时,模型值的范围不会改变)

以下是完整代码:

ng-model

模板:

editor-control

用法:

    (function () {
    'use strict';

    var module = angular.module('nokia');

    module.directive('optionalEditor', function () {
        return {
            templateUrl: 'plugins/acc/app/common/optional-editor/optional-editor.html',
            restrict: 'E',
            require: '?ngModel',
            replace: true,
            transclude: {
                'editor': 'editorControl'
            },
            scope: true,
            link: function (scope, element, attrs, ngModelCtrl,transcludeFn) {
                scope.model = {};
                scope.model.viewValue = 'Not set';
                scope.model.beingEdited = false;

                if (ngModelCtrl) {
                    scope.toggleEditMode = function (doApply) {
                        if (scope.model.beingEdited) {
                            if (doApply) {
                                ngModelCtrl.$setViewValue(scope.model.editValue);
                            }
                        } else {
                            scope.model.editValue = ngModelCtrl.$viewValue;
                        }
                        scope.model.beingEdited = !scope.model.beingEdited;
                    };

                    ngModelCtrl.$render = function () {
                        scope.model.viewValue = this.$viewValue ? this.$viewValue : 'Not set';
                    };
                }
                transcludeFn(scope, function (clone, sc) {
                var eControl = clone.children();
                eControl.attr("ng-model", "model.editValue");
                element.find('editor-control').replaceWith(clone);
            });
            }
        }
    });
})(window);

我希望<div> <a ng-show="!model.beingEdited" ng-click="toggleEditMode()" href>{{model.viewValue}}</a> <div ng-show="model.beingEdited"> <div class="row"> <div class="col-xs-8"> <ng-transclude ng-transclude-slot="editor"></ng-transclude> </div> <button type="button" class="btn btn-primary" title="Apply" ng-click="toggleEditMode(true)"><i class="fa fa-check"></i> </button> <button type="button" class="btn btn-default" title="Cancel" ng-click="toggleEditMode(false)"><i class="fa fa-ban"></i> </button> </div> </div> <optional-editor ng-model="parameter.value" class="col-sm-6"> <editor-control> <input class="form-control" type="number" id="{{metaDs.id}}" placeholder="integer value"> </editor-control> </optional-editor> 绑定到指令范围的值。也许有人可以建议怎么做?

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是指令transcludeFn函数中引入的link回调。这允许您为已转换的内容指定范围,这意味着您可以在已转换内容的元素中添加ng-model属性,并仍然可以通过指令的范围访问它。

以下是您将如何执行此操作的示例:

要转换的标记中的

<input type="number" ... ng-model="ngModel">
在transcluding指令中

...
link: function (scope, element, attrs, ngModelCtrl, transclude) {
...
  // this function applies the scope in it's first parameter to the 
  // transcluded markup, clone is the transcluded content
  transclude(scope, function(clone, scope) {

    // append the transclude content to your directive's element, 
    // or any other element you choose
    element.append(clone);
  }

使用transcludeFn是必要的,因为默认情况下,您的transclude内容将使用父控制器的范围,您将无法直接在您的指令中修改它。

更新 - 动态ng-model

要动态地向您的指令添加ng-model属性,您需要将该属性添加到transclude函数中的clone元素并编译它:

transclude(scope, function(clone, scope) {
  var target = angular.element( document.querySelector('#transclude-contents') );
  clone.attr('ng-model', 'ng-model');
  $compile(clone)(scope);
  target.append(clone);
});

这是更新的plnkr:http://plnkr.co/edit/WKX8562vD0OvokR6Mujv?p=preview