嵌套 - 被抄送的项目 - 范围澄清?

时间:2015-12-08 17:46:04

标签: angularjs angularjs-ng-transclude

我已经知道如何进行翻译(仅在第一级内我猜),我对嵌套的被抄送项目的范围有疑问。

好的,我有这段代码:

<body ng-app="docsTabsExample" ng-controller="ctrl">
  <my-tabs>
    <my-pane title="Hello">
      <h4>Hello , The value of "i" is => {{i}}</h4>
   </my-pane>
  </my-tabs>
</body>

基本上我有一个controller<my-tabs><my-pane >

查看myTabs指令:

  .directive('myTabs', function()
  {
      return {
          restrict: 'E',
          transclude: true,
          scope:
          {},
          controller: ['$scope', function($scope)
          {
              $scope.i = 2;
          }],
          template: '<div ng-transclude></div>'
      };
  })

我知道指令的内容可以访问外部指令的范围

因此黄色部分可以访问外部作用域(这是主控制器作用域):

enter image description here

以下是myPane指令的代码:

  .directive('myPane', function()
  {
      return {
          require: '^myTabs',
          restrict: 'E',
          transclude: true,
          scope:
          {
          },
          controller: function($scope)
          {
              $scope.i = 4; //different value
          },
          template: '<div  ng-transclude></div>'
      };
  })

该计划以:

开头
.controller('ctrl', function($scope)
{
    $scope.i = 1000;
})

该计划的输出是:

  

你好,&#34; i&#34;的价值是=&gt; 1000

但是

根据文档:myPane's被转换的数据应该可以访问指令的外部范围,该指令是myTabs指令,其值为i=2

但是myPane有一个隔离的范围,因此它 NOT myTabs继承范围。

问题

因此,为了获得i=1000,控制器的范围会更高一层更多更高? (澄清,我不会问我如何让i获得另一个值 - 我问为什么/如何具有1000的值。

我的意思是范围的层次结构在这里看起来如何?

是这样的吗?

         controller's scope
                |
       +--------+---------+
       |                  |
  myTabs's             mypanes's
 transcluded           transcluded 
 data's scope          data's scope         

文档说:

  

transclude选项会更改范围嵌套的方式。它成功了   因此,被转换的指令的内容具有任何范围   在指令之外,而不是内部的任何范围。在   这样做,它使内容访问外部范围。

但是myPAne指令的外部有什么范围?

换句话说,为什么/ 如何i=1000

FULL PLUNKER

在回答后编辑OP

安装和配置PeriScope后(来自@MarkRajcok)我现在可以直观地看到它:

enter image description here

1 个答案:

答案 0 :(得分:1)

来自$compile

上的文档
  

当你调用一个transclude函数时,它会返回一个DOM片段   预先绑定到一个翻译范围。这个范围很特殊,因为它   是指令范围的子节点(因此当它被销毁时会被销毁)   指令的范围被破坏)但它继承了属性   它的范围。

层次结构(来自$$ childTail)如:

/*navigation icon animation*/
var trigger = 'X';

jQuery(document).ready(function () {
$('#toggle-menu').click(function () {
trigger = 'X';
$(this).toggleClass('menu-is-active')

});

/* click outside of nav to trigger navigation icon animation*/
$(document).click(function () {


if (trigger == 'X') {
$("#toggle-menu").toggleClass();
trigger = 'ham';
}

});
$("nav").click(function (e) {
e.stopPropagation();
return false;
});
/*----/----navigation icon animation*/

/*toggle menu*/
jQuery("#toggle-menu").click(function () {
jQuery(".nav").slideToggle();
if($("div.header").hasClass("whitenavbar") == false){
$("div.header").addClass("whitenavbar bg navup ");
}else{
$("div.header").removeClass("whitenavbar bg navup");
}

});



/* click outside of nav to close toggle*/
$(document).click(function () {
$(".nav").hide();
});
$("#toggle-menu").click(function (e) {
e.stopPropagation();
return false;
});
/*----/----toggle menu*/

/*navigation background fade in fade out */
$(window).scroll(function () {
    var dist = $('#panel2').offset().top;
    console.log(dist);
    if ($(window).scrollTop() > dist) {
        $('.header').addClass('bg');
        $('.header').addClass('navfade');
    }
    else {
        $('.header').removeClass('bg');
    }


});


$('.scroll').on('click', function (e) {
    e.preventDefault()

    $('html, body').animate({
        scrollTop: $(this.hash).offset().top
    }, 1500);
});

/*----/-----navigation background fade in fade out */

});

原型层次结构就像(来自AngularJS Batarang的截图) -

ng-transclude proto hierarchy

更新了plunker,并在控制台中打印了范围ID,可以让您更好地了解。

为什么这些不同,我不太确定。有人可以对此有所了解。

为什么值为1000.因为 i 需要作为双向属性 = 提供,所以子范围可以修改它。我已经更新了上面的plunker,您现在可以看到该值响应/*navlist*/ .navigation{ width:100%; background: #fff; padding-top: 40px; padding-bottom: 40px; } .navlist { display: inline-block; } .navlist:after { content: ''; display: block; height: 1.5px; width: 0; background: transparent; transition: width .5s ease, background-color .5s ease; } .navlist:hover:after { width: 100%; background: grey; transition: width .5s ease, background-color .5s ease; } /*----/----navlist*/ /*global styles*/ body { width: 100%; margin: 0; list-style: none; text-decoration: none; font-size:1.05em; font-family: Helvetica Neue, Helvetica, Arial, Sans-serif; } a { font-size:1.05em; font-family: Helvetica Neue, Helvetica, Arial, Sans-serif; background:transparent; color: grey; border:none; letter-spacing:0.15em; text-transform:uppercase; transition: color 0.5s ease; list-style: none; text-decoration: none; } /*----/----global styles*/ /*navigation icon*/ #toggle-menu { float:right; display: block; width: 15px; height: 15px; padding: 20px; } #toggle-menu div { width: 15px; height: 15px; position: relative; } .header #toggle-menu span { display: block; width: 15px; height: 3px; position: absolute; -webkit-transition: -webkit-transform 0.2s ease-in-out, top 0.2s ease-in-out 0.2s, opacity 0.2s ease-in-out 0.2s; -moz-transition: -moz-transform 0.2s ease-in-out, top 0.2s ease-in-out 0.2s, opacity 0.2s ease-in-out 0.2s; transition: transform 0.2s ease-in-out, top 0.2s ease-in-out 0.2s, opacity 0.2s ease-in-out 0.2s; -webkit-transform-origin: center; -moz-transform-origin: center; transform-origin: center; } #toggle-menu span.top { top: 0px; } #toggle-menu span.middle { top: 6px; } #toggle-menu span.bottom { top: 12px; } /*----/----navigation icon*/ /*navigation background transition*/ .bg { background-color: #fff !important; border-bottom: 0.5px solid rgba(0, 0, 0, 0.2); } .show { opacity: 1; } .navfade { -webkit-transition: all 1s ease-in-out; -moz-transition: all 1s ease-in-out; -o-transition: all 1s ease-in-out; transition: all 1s ease-in-out; } .header .logo { /* Before scroll */ color: white; } .bg .logo { /* After scroll */ color: #545454; } .navinstagram { fill: #fff } .bg .navinstagram{ fill: #545454; } #toggle-menu span{ background: #fff; } .bg #toggle-menu span { background: #545454; } /*----/----navigation background transition*/ /*navigation icon animation*/ #toggle-menu.menu-is-active span { -webkit-transition: -webkit-transform 0.2s ease-in-out 0.2s, top 0.2s ease-in-out, opacity 0.2s ease-in-out; -moz-transition: -moz-transform 0.2s ease-in-out 0.2s, top 0.2s ease-in-out, opacity 0.2s ease-in-out; transition: transform 0.2s ease-in-out 0.2s, top 0.2s ease-in-out, opacity 0.2s ease-in-out; } #toggle-menu.menu-is-active span.top, #toggle-menu.menu-is-active span.middle { top: 6px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } #toggle-menu.menu-is-active span.middle { opacity: 0; } #toggle-menu.menu-is-active span.bottom { top: 6px; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); transform: rotate(-45deg); } /*----/----navigation icon animation*/ /*Nav Bar*/ .header { /*border-bottom: 0.5px solid rgba(0,0,0,.2);*/ width: 100%; position: fixed; top: 0; left: 0; z-index: 99999; background-color: rgb(184, 184, 184); /*background: none;*/ } .whitenavbar { background: white; } .nav { display: none; list-style-type: none; position: fixed; width: 100%; text-align: center; left:0; top: 55px; border-bottom: 1px solid rgba(0, 0, 0, .2); border-top: 1px solid rgba(0, 0, 0, .2); cursor: pointer; color: #545454; font-size:.8em; letter-spacing:0.05em; } .nav li { padding-left: 30px; padding-right: 30px; background: #fff; margin-top: 50px; margin-bottom: 50px; } .seemore { display: inline-block; padding-right: 20px; } #navpromo { border-top: 1px solid rgba(0, 0, 0, .2); padding-bottom: 10px; background: #ffffff; overflow: hidden; } #navpromo ul { margin: 0; } .want{ display: inline-block; text-align: center; float: left; padding-right:10px; margin-bottom: 0; } .check{ text-align: center; display:inline-block; } @media only screen and (max-width: 555px) { .want{ display: block; text-align: center; float: none; padding-right: 0px; margin-bottom: 0; } .check{ text-align: center; display: block; } } .instbtn-cont { display: inline-block; text-align: center; margin-top: 10px; padding-bottom: 30px; } .instbtn-cont .instbtn { position: relative; padding: 15px 20px; border: 1px solid grey; color: grey; -webkit-font-smoothing: antialiased; } .instbtn-cont .instbtn:hover { border: none; } .instbtn-cont .instbtn:hover .line-1 { -webkit-animation: move1 1500ms infinite ease; animation: move1 1500ms infinite ease; } .instbtn-cont .instbtn:hover .line-2 { -webkit-animation: move2 1500ms infinite ease; animation: move2 1500ms infinite ease; } .instbtn-cont .instbtn:hover .line-3 { -webkit-animation: move3 1500ms infinite ease; animation: move3 1500ms infinite ease; } .instbtn-cont .instbtn:hover .line-4 { -webkit-animation: move4 1500ms infinite ease; animation: move4 1500ms infinite ease; } .instbtn-cont .line-1 { content: ""; display: block; position: absolute; width: 1px; background-color: grey; left: 0; bottom: 0; } .instbtn-cont .line-2 { content: ""; display: block; position: absolute; height: 1px; background-color: grey; left: 0; top: 0; } .instbtn-cont .line-3 { content: ""; display: block; position: absolute; width: 1px; background-color: grey; right: 0; top: 0; } .instbtn-cont .line-4 { content: ""; display: block; position: absolute; height: 1px; background-color: grey; right: 0; bottom: 0; } @-webkit-keyframes move1 { 0% { height: 100%; bottom: 0; } 54% { height: 0; bottom: 100%; } 55% { height: 0; bottom: 0; } 100% { height: 100%; bottom: 0; } } @keyframes move1 { 0% { height: 100%; bottom: 0; } 54% { height: 0; bottom: 100%; } 55% { height: 0; bottom: 0; } 100% { height: 100%; bottom: 0; } } @-webkit-keyframes move2 { 0% { width: 0; left: 0; } 50% { width: 100%; left: 0; } 100% { width: 0; left: 100%; } } @keyframes move2 { 0% { width: 0; left: 0; } 50% { width: 100%; left: 0; } 100% { width: 0; left: 100%; } } @-webkit-keyframes move3 { 0% { height: 100%; top: 0; } 54% { height: 0; top: 100%; } 55% { height: 0; top: 0; } 100% { height: 100%; top: 0; } } @keyframes move3 { 0% { height: 100%; top: 0; } 54% { height: 0; top: 100%; } 55% { height: 0; top: 0; } 100% { height: 100%; top: 0; } } @-webkit-keyframes move4 { 0% { width: 0; right: 0; } 55% { width: 100%; right: 0; } 100% { width: 0; right: 100%; } } @keyframes move4 { 0% { width: 0; right: 0; } 55% { width: 100%; right: 0; } 100% { width: 0; right: 100%; } } /*----/----Nav Bar*/ /*in*/ .in { float:left; display: inline-block; width: 25px; height: 25px; padding: 15px; cursor: pointer; color: #fff; font-size:.8em; letter-spacing:0.05em; border-top: 0.5px solid rgba(0, 0, 0, .2); } /*----/----in*/ /*logo*/ .logo { position: absolute; left: 47%; display: inline-block; width: 15px; height: 15px; padding: 18px; cursor: pointer; color: #fff; font-size:.8em; letter-spacing:0.05em; } /*----/----logo*/ /****landscape****/ @media only screen and (max-width: 555px) { .nav li{ display: block; margin-top: 20px; margin-bottom: 20px; } .navlist:after { content: ''; display: block; height: 1.5px; width: 0; background: transparent; transition: width .5s ease, background-color .5s ease; } .navlist:hover:after { width: 100%; background: grey; transition: width .5s ease, background-color .5s ease; } } /*----/----Landscape*/控制器中的更改。

更多关于被抄送的范围 -
Confused about Angularjs transcluded and isolate scopes & bindings
https://github.com/angular/angular.js/wiki/Understanding-Scopes