【问题标题】:How to bind content of tag into into directive's scope?如何将标签的内容绑定到指令的范围内?
【发布时间】:2014-10-28 14:13:16
【问题描述】:

假设我有这样的指令:

<my-directive>This is my entry!</my-directive>

如何将元素的内容绑定到指令的范围内?

myApp.directive('myDirective', function () {
    return {
        scope : {
            entry : "" //what goes here to bind "This is my entry" to scope.entry?
        },
        restrict: "E",
        template: "<textarea>{{entry}}</textarea>"
        link: function (scope, elm, attr) {
        }
    };
});

【问题讨论】:

  • 首先如何将内容添加到 html 中?通常是 $scope 定义了在视图中显示的内容,而不是周围的方式。
  • 这个元素的内容是在服务器端添加的。角度模板是使用 PHP 应用程序生成的,因为在这种情况下内容不能以 RESTfully 的形式使用。我可以将内容添加为属性,但鉴于此指令的行为类似于&lt;textarea&gt;,为了便于开发人员理解,我希望继续使用&lt;textarea&gt;
  • 我认为旧版本的 IE 不喜欢带有元素名称的指令,这就是首选属性或类的原因。不确定这是否是您用例的一部分,但值得考虑奶奶的 IE6。

标签: angularjs angular-directive


【解决方案1】:

我认为已经给出的解决方案要简单得多。据我了解,您希望在指令初始化期间将元素的内容绑定到范围。

鉴于此 html:

<textarea bind-content ng-model="entry">This is my entry!</textarea>

定义bind-content如下:

directive('bindContent', function() {
  return {
    require: 'ngModel',
    link: function ($scope, $element, $attrs, ngModelCtrl) {
      ngModelCtrl.$setViewValue($element.text());
    }
  }
})

这是demo

【讨论】:

    【解决方案2】:

    您需要在指令中添加一个 模板 配置。

    myApp.directive('myDirective', function () {
      return {
        scope : {
          entry : "=" //what goes here to bind "This is my entry" to scope.entry?
        },
        template: "<div>{{ entry }}</div>", //**YOU DIDN'T HAVE A TEMPLATE**
        restrict: "E",
        link: function (scope, elm, attr) {
          //You don't need to do anything here yet
        }
      };
    });
    
    myApp.controller('fooController', function($scope){
      $scope.foo = "BLAH BLAH BLAH!";
    });
    

    然后像这样使用你的指令:

    <div ng-controller="fooController">
      <!-- sets directive "entry" to "foo" from parent scope-->
      <my-directive entry="foo"></my-directive>
    </div>
    

    Angular 会把它变成:

    <div>THIS IS MY ENTRY</div>
    

    假设您已正确设置角度并将此 JS 文件包含到您的页面中。

    编辑

    听起来您想要执行以下操作:

    <my-directive="foo"></my-directive>
    

    这对于 ELEMENT 指令是不可能的。但是,它具有属性指令。检查以下内容。

    myApp.directive('myDirective', function () {
      return {
        template: "<div>{{ entry }}</div>", //**YOU DIDN'T HAVE A TEMPLATE**
        restrict: "A",
        scope : {
          entry : "=myDirective" //what goes here to bind "This is my entry" to scope.entry?
        },
        link: function (scope, elm, attr) {
          //You don't need to do anything here yet
        }
      };
    });
    

    然后像这样使用它:

    <div my-directive="foo"></div>
    

    这会将传递给 my-directive 的值设置为一个名为 entry 的范围变量。不幸的是,没有办法使用元素限制指令来做到这一点。阻止它发生的不是 Angular,而是 html5 指南使您想要做的事情变得不可能。您将不得不使用属性指令而不是元素指令。

    【讨论】:

    • 啊,是的。我忘记了模板。我添加了它,你可以看到我想要完成的事情。我正在尝试将数据从使用指令的位置移动到链接函数中。当数据作为属性包含在指令标签中时,这很容易实现,但不清楚如何从标签内获取内容。
    • 你的回答没有回答问题。
    • 现在怎么样?有一个如何在控制器中使用指令的示例。我在指令配置中修复了范围声明。
    • 我希望将指令标签内的内容绑定到指令的范围内,而不是使用属性。
    【解决方案3】:

    我可能已经找到了解决方案。它依赖于指令的嵌入功能。它有效,但在确定这是正确的方法之前,我需要更好地理解嵌入。

    myApp.directive('myDirective', function() {
        return {
            scope: {
            },
            restrict: 'E',
            replace: false,
            template:   '<form>' +
                            '<textarea ng-model="entry"></textarea>' +
                            '<button ng-click="submit()">Submit</button>' +
                        '</form>',
            transclude : true,
            compile : function(element,attr,transclude){
    
                return function (scope, iElement, iAttrs) {
    
                    transclude(scope, function(originalElement){
                        scope.entry = originalElement.text(); // this is where you have reference to the original element.
                    });
    
    
                    scope.submit = function(){
                        console.log('update entry');
                    }
                }
            }
        };
    });
    

    【讨论】:

    • 虽然这可行,但您将值的键 (entry) 放在两个不同的位置(模板和链接函数)。最好保持ng-model="entry" 不变,但在我的回答中使用ngModelCtrl.$setViewValue 而不是scope.entry
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多