0

我目前正在構建一個模式指令,我可以使用它來填充某些數據表。我有一個名爲modal-visible的指令屬性,它將是一個布爾值,默認爲false。如果缺省值爲真,則在載入時,模態可見。但是,當我最初將其設置爲false並更改事件的值時,屬性會更改,但指令不會選擇更改。我在該指令的鏈接部分有一個手錶,但只能看到最初的變化。自定義指令不會對屬性更改做出反應

下面是我的代碼示例。我只有一個簡單的測試頁面,帶有按鈕和模式。模態屬性modal-visible設置爲'false'。單擊按鈕時,模式的模態可見屬性更新爲「真」,但模式不顯示在頁面上。有人能指導我解決這個問題,並且還能爲我解釋爲什麼會發生這種情況嗎?謝謝。

testing.html

<button id="btn1" class="btn btn-default">Click Me</button> 
<modal id="chartModal" modal-title="Testing a Modal" modal-visible="false"> 
    <p>Body</p> 
</modal> 

<script type="text/javascript"> 
    var modal = $("#chartModal"); 
    var btn = $("#btn1"); 

    btn.on("click", function() { 
     modal.attr("modal-visible", "true"); 
    }) 
</script> 

modal.js

(function() { 

    var app = angular.module("contactAuthApp"); 


////////////////////////// 
// BEGIN - DIRECTIVES 
////////////////////////// 

    var modalDirective = function() { 
     return { 
      restrict: "E", 
      scope: { 
       modalVisible: "=", 
       modalTitle: "@" 
      }, 
      transclude: true, 
      controller: function($scope) { 

      }, 
      templateUrl: "utils/modal.html", 
      link: function (scope, element, attrs) { 
       //Attach base classes 
       element.addClass("modal fade"); 

       //Hide or show the modal 
       scope.showModal = function (visible) { 
        if (visible) { 
         element.modal("show"); 
        } else { 
         element.modal("hide"); 
        } 
       } 

       //Check to see if the modal-visible attribute exists 
       if (!attrs.modalVisible) { 

        //The attribute isn't defined, show the modal by default 
        scope.showModal(true); 

       } else { 

        //Watch for changes to the modal-visible attribute 
        scope.$watch("modalVisible", function (newValue, oldValue) { 
         scope.showModal(newValue); 
        }); 

        //Update the visible value when the dialog is closed through UI actions (Ok, cancel, etc.) 
        element.bind("hide.bs.modal", function() { 
         scope.modalVisible = false; 
         if (!scope.$$phase && !scope.$root.$$phase) 
          scope.$apply(); 
        }); 

       } 
      } 
     }; 
    } 

////////////////////////// 
// END - DIRECTIVES 
////////////////////////// 


    app.directive("modal", modalDirective); 

})(); 

modal.html(指令模板)

<div class="modal-dialog"> 
    <div class="modal-content"> 
     <div class="modal-header"> 
      <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 
      <h4 class="modal-title">{{modalTitle}}</h4> 
     </div> 
     <div class="modal-body"> 
      <div data-ng-transclude></div> 
     </div> 
     <div class="modal-footer"> 
      <button type="button" class="btn btn-default pull-right" data-dismiss="modal">Close</button> 
     </div> 
    </div> 
</div> 

EDITED

嘿runTarm:這裏是我更新的代碼,將modalVisible的隔離範圍更改爲'@'並觀察鏈接中的屬性。仍然無法得到它的工作:

var modalDirective = function() { 
    return { 
     restrict: "E", 
     scope: { 
      modalVisible: "@", 
      modalTitle: "@" 
     }, 
     transclude: true, 
     controller: function($scope) { 

     }, 
     templateUrl: "utils/modal.html", 
     link: function (scope, element, attrs) { 

      //Attach base classes 
      element.addClass("modal fade"); 

      //Hide or show the modal 
      scope.showModal = function (visible) { 
       if (visible === true) { 
        element.modal("show"); 
       } else { 
        element.modal("hide"); 
       } 
      } 

      //Watch for changes to the modal-visible attribute 
      attrs.$observe("modalVisible", function (val) { 
       console.log(val); 
       scope.showModal(val); 
      }); 

      //Update the visible value when the dialog is closed through UI actions (Ok, cancel, etc.) 
      element.bind("hide.bs.modal", function() { 
       scope.modalVisible = false; 
       if (!scope.$$phase && !scope.$root.$$phase) 
        scope.$apply(); 
      }); 

     } 
    }; 
} 

回答

0

雙向一條指令的隔離範圍和父範圍之間的結合不能用恆定那樣被使用。

<modal modal-visible="false"> // false is a constant boolean value not a variable in the parent scope 

您必須選擇繼續使用雙向綁定還是使用自定義監視功能來檢測屬性更改。例如,請參閱http://plnkr.co/edit/ZwrL6qlKTQCWZJ3EsXdM?p=preview

在上面的plunker,modal-two使用雙向綁定:

<button id="btn2" class="btn btn-default" ng-click="isModalVisible = true">Click Me v2</button> 
<modal-two id="chartModal2" modal-title="Testing a Modal" modal-visible="isModalVisible"> 
    <p>Body</p> 
</modal-two> 

modal使用自定義手錶功能:

scope.$watch(function() { 
    return element.attr('modal-visible'); 
}, function (newValue, oldValue) { 
    scope.showModal(newValue === 'true'); 
}); 

不過,我想discorage使用的自定義監視功能,這不是一種角色方式,可能會導致性能問題。

+0

太棒了!我很感激。 – user3845941

+0

對不起,我的誤解,'$ attr。$ observe()'在這種情況下不能使用。您可以使用自定義監視功能來檢測屬性更改,但我不推薦它。請參閱plunker中的模式二示例。 – runTarm

+0

使用雙向綁定進行操作,我是否也可以在指令中創建控制器,還是必須在指令之外? – user3845941

2

你有別的塊手錶這個條件!attrs.modalVisible,因此它被觸發該條件而失敗。修改指令(去除的if-else塊)類似下面:

//Watch for changes to the modal-visible attribute 
scope.$watch("modalVisible", function (newValue, oldValue) { 
    if(newValue) { 
     scope.showModal(newValue); 
    } else { 
     //Update the visible value when the dialog is closed 
     //through UI actions (Ok, cancel, etc.) 
     element.bind("hide.bs.modal", function() { 
      scope.modalVisible = false; 
      if (!scope.$$phase && !scope.$root.$$phase) 
       scope.$apply(); 
     }); 
    } 
}); 
+0

我試圖取出if-else塊並將其替換爲您的代碼,仍然無法正常工作。還有其他建議嗎? – user3845941

+0

注意一件簡單的事情:由於隔離範圍變量是雙向綁定的,因此它可以從指令的父範圍更改。因此,你正在觀看它。每次手錶被觸發時,變量的可能值爲空,未定義,真,假。現在,無論您需要在手錶內部使用您自己的邏輯,以獲得所有這些可能的場景。說得通? :) – dmahapatro

+0

因爲事件發生在angular之外可能更好使用'attrs。$ observe'而不是'scope。$ watch'。就我個人而言,我認爲擺脫jQuery是更明智的做法,並在內部完成所有內部角 – charlietfl

相關問題