2014-09-29 78 views
0

我試圖在窗體上添加一個簡單的「切換」。如果我點擊一個按鈕,那麼我應該激活一個相應命名的部分,否則應該隱藏視圖。我的問題似乎是範圍之一。如果我沒有在子步驟中使用隔離範圍,那麼這兩個子步驟在一個切換點上將顯示爲激活狀態,而在另一個子切換點上處於非激活狀態(這是不正確的行爲)。如果我使用一個孤立的範圍,然後isActive()永遠不會被調用。ng-show沒有按預期方式綁定

我的代碼如下。

<div ng-controller='SubstepCtrl'> 
    <button activates='CreateNewMeter'> 
     Create new Meter 
    </button> 

    <button activates='UseExistingMeter'> 
     Use Existing Meter 
    </button> 

    <div class='sub-step' substep='CreateNewMeter' ng-show='isActive(name)'> 
     <h1>Create New Meter</h1> 
    </div> 

    <div class='sub-step' substep='UseExistingMeter' ng-show='isActive(name)'> 
     <h1>Use Existing Meter</h1> 
    </div> 
</div> 

角:

.controller('SubstepCtrl', function($scope) { 
    $scope.activeSubstepName = undefined; 
    $scope.isActive = function(name) { 
     return $scope.activeSubstepName == name; 
    }; 
}) 

.directive('activates', function() { 
    return { 
     link: function($scope, $element, $attrs) { 
      $element.on('click', function() { 
       $scope.activeSubstepName = $attrs.activates; 
       $scope.$apply(); 
      }); 
     } 
    }; 
}) 

.directive('substep', function() { 
    return { 
     link: function($scope, $element, $attrs) { 
      $scope.name = $attrs.substep; 
     } 
    }; 
}); 

我設法在使用jQuery相當哈克的方式來實現這一點,但我不知道是否有一種方式來角IFY它。

預期的行爲是,如果我點擊「創建新儀表」按鈕,應該顯示「CreateNewMeter」子步驟,並且「UseExistingMeter」不應該顯示。據我瞭解這裏的問題是子步驟div不創建一個子範圍,都使用父範圍 - 因此名稱是未定義的 - 對嗎?

如果是這樣,我該如何補救?

+0

對不起,是的,我跳過了這一點。但是它在實際代碼中是$ scope.activeSubstepName。 – 2014-09-29 13:23:14

+0

您的子步驟指令將控制器中的$ scope.name設置爲頁面上最後一個子步驟元素的名稱,這就是爲什麼您看到它們都顯示出來(它們都使用相同的「標誌」) – JoseM 2014-09-29 13:26:25

+0

您需要傳遞名稱妥善.. http://plnkr.co/edit/2KowNF?p =預覽You'r子步驟只使用控制器範圍,因此範圍中的name屬性將被指令的最後一個實例覆蓋。 – PSL 2014-09-29 13:27:43

回答

0

這裏是您創建一個新的指令與它的一個解決方案擁有孤立的範圍。在我看來,這是一個更好的解決方案,尤其是因爲它可以讓你擁有儘可能多的子步驟。

在指令中創建隔離作用域時需要執行的操作對於nameisActive函數都有屬性。由於name只是您在html中定義的字符串,因此您可以將其指定爲@屬性,以便在指令中將其設置爲您在html中指定的字符串。我創建了函數(將它傳遞給使用&語法的指令)稱爲showWhen,如果您注意到,爲了傳入您在html中的函數中指定的參數name,您需要傳遞一個對象您的指令使用name作爲鍵值,指令name作爲值。

的HTML:

<div ng-controller='SubstepCtrl'> 
    <button activates='CreateNewMeter'> 
     Create new Meter 
    </button> 

    <button activates='UseExistingMeter'> 
     Use Existing Meter 
    </button> 

    <button activates='UseImaginaryMeter'> 
     Use Imaginary Meter 
    </button> 

    <button activates='none'> 
     "Clear" all 
    </button> 

    <substep name="CreateNewMeter" show-when="isActive(name)"> 
     <h1>Create New Meter</h1> 
    </substep> 

    <substep name="UseExistingMeter" show-when="isActive(name)"> 
     <h1>Use Existing Meter</h1> 
    </substep> 

    <substep name="UseImaginaryMeter" show-when="isActive(name)"> 
     <h1>Use Imaginary Meter</h1> 
    </substep> 
</div> 

該指令代碼:

.directive('substep', function() { 
    return { 
     restrict: 'E', 
     scope: { 
     name: '@', 
     showWhen: '&' 
     }, 
     transclude: true, 
     template: '<div ng-transclude class="sub-step" ng-show="showWhen({name:name})"></div>' 
    }; 
}); 

這裏是一個示例plunker:http://plnkr.co/edit/TKJehABKIPPHRbrUrqr3?p=preview

+0

你能解釋一下'&'做什麼? :)我知道我可以谷歌它,但我爲了完整起見,以防其他人在這個問題上絆倒。 – 2014-09-29 14:22:16

+0

當你想傳遞一個指向該指令的指針以便能夠從你的控制器作用域調用一個函數時,你可以在隔離作用域定義對象中使用'&'。請參閱[指令範圍文檔](https://docs.angularjs.org/api/ng/service/$compile#-scope-)以獲取更多信息 – JoseM 2014-09-29 14:31:25

+0

將此標記標記爲已接受,因爲它不受2個選項的限制。如果這是一個人造pais我道歉:( – 2014-09-29 14:33:23

0

試試這個,它避免了創建自己的指令:

<div ng-controller='SubstepCtrl'> 
    <button ng-click='setMeter("new")'> 
     Create new Meter 
    </button> 

    <button activates='setMeter("existing")'> 
     Use Existing Meter 
    </button> 

    <div class='sub-step' substep='CreateNewMeter' ng-show='meter === "new"'> 
     <h1>Create New Meter</h1> 
    </div> 

    <div class='sub-step' substep='UseExistingMeter' ng-show='meter === "existing"'> 
     <h1>Use Existing Meter</h1> 
    </div> 
</div> 

設置的函數,你的控制器的範圍:

.controller('SubstepCtrl', function($scope) { 
    $scope.activeSubstepName = undefined; 
    $scope.isActive = function(name) { 
     return $scope.activeSubstepName == name; 
    }; 
    $scope.meter = null; 
    $scope.setMeter = function(meterType) { 
     $scope.meter = meterType; 
    }; 
}); 
+0

這是一個體面的解決方案,但是如果我有多個子步驟,它會中斷。這就是說我的問題只允許兩個子步驟,所以我想它會這樣做:p – 2014-09-29 13:56:42

+0

請參閱問題更新 – Fordio 2014-09-29 14:00:44

+0

謝謝男人 - 這是完美的。:) – 2014-09-29 14:00:52

相關問題