【问题标题】:Angular 1.4 View Encapsulation and Shadow DOM - is it possible?Angular 1.4 View Encapsulation 和 Shadow DOM - 有可能吗?
【发布时间】:2015-10-12 05:18:44
【问题描述】:

出于稳定性原因,我正在将我的应用程序从使用 Polymer 更改为 Angular 1.4。由于我熟悉 Polymer 和 Web 组件(以及未来使用 Angular 2),我选择使用 Component Pattern 来构建我的应用程序。

我已经搜索过,到目前为止只遇到了this question,解决方案是不再维护的 github 存储库。我想知道是否可以使用 Angular 1.4 进行视图封装。如果我说错了,具体来说,我的带有模板的指令是否可以像 Polymer 和 Angular 2 那样在不依赖 Grunt 的情况下拥有自己的封装样式?

【问题讨论】:

    标签: angularjs polymer encapsulation shadow-dom


    【解决方案1】:

    好像是这样。我在测试中使用了 Angular 1.6,但我能够让 shadow DOM 在 angular 指令中工作,包括绑定。

    这是我的示例代码:

    <!DOCTYPE html>
    <html ng-app="app">
      <head>
        <meta charset="utf-8">
        <title>Angular 1.x ShadowDOM example</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
        <script>
        var app = angular.module('app', []);
    
        app.controller('myElController', ($scope) => {
    
        });
    
        var template = `
        <style>
        :host {
          left: 50%;
          position: fixed;
          top: 50%;
          transform: translate(-50%,-50%);
          border: 1px solid black;
          box-shadow: 4px 4px 4px rgba(0,0,0,.4);
          display: inline-block;
          padding: 6px 12px;
        }
    
        h3 {
          border-bottom: 1px solid #999;
          margin: 0 -12px 8px;
          padding: 0 12px 8px;
        }
    
        p {
          margin: 0;
        }
        </style>
            <h3>{{title}}</h3>
          <p>{{info}}</p>
        `;
    
        app.directive('myEl', ($compile) => {
            return {
              "restrict": "E",
              "controller": "myElController",
              "template": '',
              "scope": {
                "title": "@",
                "info": "@"
              },
              "link": function($scope, $element) {
                console.log('here');
                $scope.shadowRoot = $element[0].attachShadow({mode:'open'});
                $scope.shadowRoot.innerHTML = template;
                $compile($scope.shadowRoot)($scope);
              }
            };
        });
        </script>
      </head>
      <body>
        <div>
          <my-el title="This is a title" info="This is the info of the element"></my-el>
        </div>
        <div class="shell">
          <h3>Outside title (H3)</h3>
          <p>Outside content (P)</p>
        </div>
      </body>
    </html>
    

    诀窍是没有指令的默认模板。只是我们一个空字符串。然后,在link 函数中,您将创建影子根并将其innerHTML 设置为您的真实模板。然后你需要在影子根上运行$compile 以将其绑定回指令的$scope。

    请注意,这只适用于原生支持 shadow DOM 的浏览器。任何 Polyfill 都不支持真正的 CSS 封装。为此,最好使用一种 BEM CSS 形式:http://getbem.com/introduction/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 2019-11-14
      • 2014-10-02
      • 2016-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多