angularjs为特定类型的所有html元素提供自己的范围

时间:2015-08-17 21:45:07

标签: javascript angularjs angularjs-scope

我需要这样做才能使用HTML5中的<dialog>标记,我希望我的网站上的每个<dialog>都可以使用controller和{{{{}}}来访问自己的唯一范围1}}语法。

这是我认为可行的。

的Javascript

controllerAs

HTML

\\Dialog Controller 

function dialog () {
    return {
        scope: {},
        controller: function () {
            this.test = 'Dialog Test';
        },
        controllerAs: 'Dialog',
        bindToController: true
    }
} 

angular.module('app',[]).directive('dialog', dialog);

我希望在激活对话框时,<!-- Dialog HTML Example Case --> <body ng-app='app'> <dialog id='test'>{{Dialog.test}}</dialog> </body> 将评估为Dialog Test。相反,它会评估为空字符串。更重要的是,如果我向主体添加控制器,则对话框可以访问其范围。就好像我的指令中的隔离范围定义被完全忽略一样。

普拉克

请注意,由于大多数浏览器缺乏支持,我修改了plunk以使用Dialog.test而不是<span>

http://plnkr.co/edit/eXtUq7BxCajOZAp8BpVe?p=preview

3 个答案:

答案 0 :(得分:2)

您正在创建隔离范围,这是件好事。但是在AngularJS1.2版本之后,他们做了一些重大更改,其中隔离范围将完全隔离。

因此跨度指令范围仅对该指令的模板可见(跨度)。

该指令的内部html将仅获取父/当前范围而不是指令隔离范围(因为隔离范围仅对模板可见)。要打印Span.test的值,您必须创建模板并在指令中引用该模板,如下所示:

   var app = angular.module('test', []);
   function mainCtrl() {
       this.test = 'test';
   };
   function spanCtrl() {
       this.test = 'Span Test';
   }
   function span () {
       return {
           scope: {},
           controller: spanCtrl,
           controllerAs: 'Span',
           template: '{{Span.test}}'
       }
   }

    app.controller('mainCtrl', mainCtrl);
    app.directive('span', span);
  

您可以查看两个非常棒的博客,了解更多详情codeComponent In AngularJS

答案 1 :(得分:0)

元素的内容不是&#34;参见&#34;指令的隔离范围。范围是&#34;隔离&#34;意味着它与View的范围是分开的,其中其托管元素的指令和内容都驻留在该范围内。

要将内容与内部范围相关联,您需要转发它们 - 转换功能允许您将其链接到任何范围:

function dialog () {
    return {
        scope: {},
        controller: function () {
            this.test = 'Dialog Test';
        },
        controllerAs: 'Dialog',
        bindToController: true
        transclude: true.
        link: function(scope, element, attrs, ctrls, transclude){

           // scope here is the isolate scope of the directive
           transclude(scope, function cloneAttachFn(contentsClone){
             element.append(contentsClone);
           });
        }
    }
} 

上述方法可行,但了解为什么&#34;默认&#34;行为是有道理的。考虑到指令的用户,指令的内部(即隔离)功能(以及范围变量)应该是不可见的。如果不是,您的指令的用户需要知道&#34;特殊&#34;在您的情况下,范围变量,如Dialog。因此,在不知道指令如何运作的情况下,读取HTML的人不知道Dialog来自哪里。

答案 2 :(得分:0)

原始断言中存在错误:dialog指令节点

的内容
<dialog id='test'>{{Dialog.test}}</dialog>

属于父级范围,不属于属于指令范围。因此,它从父控制器(或根范围,如果没有)插入Dialog.test

可以通过以下方式实现预期的行为:

app.directive('dialog', function ($interpolate) {
  return {
    scope: {},
    controller: function ($scope) {
      this.test = 'test';
    },
    controllerAs: 'Dialog',
    compile: function (element) {
      var template = element.text();

      return function (scope, element) {
        element.text($interpolate(template)(scope));
      }
    }
  };
});

但它很难称为使用Angular的推广方式。让指令处理其模板。