簡體   English   中英

AngularJS:在transclude設置為true的指令中隔離范圍

[英]AngularJS : Isolating scope in a directive with transclude set to true

為了說明我想要實現的目標,我將提供一個不完整的手風琴小部件: http//plnkr.co/edit/aiUKTRmRk5qFqPKCy2Md?p = preview

我有兩個手風琴窗格指令,坐在我的HTML旁邊。

    <accordion-pane>
      <accordion-header>
        <h3>Pane 1</h3>
      </accordion-header>
    </accordion-pane>

    <accordion-pane>
      <accordion-header>
        <h3>Pane 2</h3>
      </accordion-header>
    </accordion-pane>

和angular / js代碼:

  .directive('accordionPane', [function () {
    return {
      transclude: true, 
      replace: true,
      //scope: {}, // Isolating the scope breaks transclusion
      templateUrl: 'accordion-pane.html',
      link: function (scope) {
        scope.toggle = function () {
          scope.active = !scope.active;
        };
      }
    };
  }])
  .directive('accordionHeader', [function () {
    return {
      templateUrl: 'accordion-header.html',
      transclude: true,
      replace: true
    };
  }]);

這些窗格已經轉換為:true,因此我在html中添加的內容將包含在他們的模板中。

每個窗格還必須包含accordion-header指令,並且此指令使用范圍變量以折疊或展開狀態顯示自身。

正如你在這個問題上看到的那個問題是,我無法正確隔離范圍。

默認行為是兩個窗格共享相同的范圍,因此當我展開一個窗格時,它們都會擴展。

如果我嘗試在accordion-pane指令上隔離范圍(通過取消注釋script.js中的范圍:{}行),那么accordion-pane的范圍不會被轉換為它的accordion-header子節點。

在我看來,這似乎是一種排列事物的邏輯方式,但顯然我錯了。 關於如何實現這一目標的任何想法,以及為什么隔離父母的范圍,使得它對孩子不可行?

編輯:正如肖恩指出的那樣:

“每角度文檔:

“transclude選項改變了嵌套范圍的方式。它使得transcluded指令的內容具有指令之外的任何范圍,而不是內部的任何范圍。這樣做,它使內容訪問到外部范圍。“”

這是有道理的,但是......我如何隔離范圍並同時使用ngTransclude?

編輯2:

Jim的建議在plunkr中表現得非常好。 所以我更新了plnkr,有一個更復雜的例子: http ://plnkr.co/edit/sbiSF8OQ2Ang99Z0OaHB?p=preview

這里的問題是,范圍似乎並沒有與手風琴窗格隔離,而是在兒童兄弟姐妹中孤立。

因此,通過將toggle函數移動到accordion-header,accordion-header和accordion-body可以訪問該范圍,但是accordion-pane(它們的父級)沒有訪問權限。

我在這里想要實現的另一個目的是隔離手風琴窗格下面的范圍,並在accordion-pane,accordion-body和accordion-header之間共享該范圍。 目前,范圍僅在accordion-body和accordion-header之間共享。

為什么指令上的孤立范圍會導致轉換中斷,我不確定。

但是,就簡單地使用您設置的模板找到解決方案而言。 為每個折疊窗格元素添加ng-if =“1”。

Per ng-if文檔

請注意,使用ngIf刪除元素時, 其范圍將被銷毀,並且在還原元素時會創建新范圍 在ngIf中創建的作用域使用原型繼承從其父作用域繼承

因此,通過向元素添加ng-if="1"屬性/指令,您將隔離范圍,因此$scope.active對每個元素都是唯一的。

你可以看看這個修訂過的Plunker示例

看起來你的問題不在於范圍界定,而在於你在哪里進行切換。 這將單獨展開和折疊每個窗格(從accordionPane切換到accordionHeader鏈接功能):

angular.module('accordion-test', [])
  .directive('accordionPane', [function () {
    return {
      transclude: true, 
      replace: true,
      //scope: {}, // Isolating the scope breaks transclusion
      templateUrl: 'accordion-pane.html'
    };
  }])
  .directive('accordionHeader', [function () {
    return {
      templateUrl: 'accordion-header.html',
      transclude: true,
      replace: true,
      link: function(scope,elem,attr,ctrl){
        scope.toggle = function () {
          scope.active = !scope.active;
        };
      }
    };
  }]);

如果你願意,我會找出一個折疊他人的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM