2015-07-09 7 views
1

У меня есть специальная директива tag-comment. он имеет 3 режима: view, edit и create.угловая пользовательская директива ng-show 2-way binding не работает

Это моя функция контроллера для тега-комментарий:

controller: function($scope) { 

     $scope.userService = userService 

     //view mode 
     $scope.showViewMode = ($scope.mode === 'view') 
     if ($scope.showViewMode) { 
      $scope.showToEdit = (userService.isAtLeastCreator($scope.entity)) 
      $scope.showOnDelete = ($scope.onDelete() && $scope.entity.status !== 'deleted' && userService.isAtLeastCreator($scope.entity)) 
      $scope.showOnUndelete = ($scope.onUndelete() && $scope.entity.status === 'deleted' && userService.isAtLeastCreator($scope.entity)) 

      $scope.showMetaUpdate = ($scope.entity.status === 'normal' && $scope.entity.meta.updatedBy && $scope.entity.meta.updatedDate) 
      $scope.showMetaDelete = ($scope.entity.status === 'deleted' && $scope.entity.meta.deletedBy && $scope.entity.meta.deletedDate) 
      $scope.showMetaBan = ($scope.entity.status === 'banned' && $scope.entity.meta.bannedBy && $scope.entity.meta.bannedDate) 

      $scope.displayNameCreatedBy = (userService.getDisplayName($scope.entity.createdBy)) 
      $scope.displayNameUpdatedBy= (userService.getDisplayName($scope.entity.meta.updatedBy)) 
      $scope.displayNameDeletedBy = (userService.getDisplayName($scope.entity.meta.deletedBy)) 
      $scope.displayNameBannedBy = (userService.getDisplayName($scope.entity.meta.bannedBy)) 

     } 

     //edit mode 
     $scope.showEditMode = ($scope.mode === 'edit') 
     if ($scope.showEditMode) { 
      $scope.showOnUpdate = $scope.onUpdate() 

     } 



     //create mode 
     $scope.showCreateMode = ($scope.mode === 'create') 
     if ($scope.showCreateMode) { 
      $scope.showOnCreate = $scope.onCreate() 
      $scope.showOnCancel = $scope.onCancel() 
     } 


    }, 

Это мой HTML шаблон:

<div class="tag-comment"> 

    <!--view mode--> 
    <div ng-if="showViewMode"> 
     <div class="my-panel"> 

      <div class="my-panel-heading"> 
       {{entity.title}} 
      </div> 

      <div class="my-panel-body"> 
       {{entity.content}} 
      </div> 

      <div class="my-panel-footer"> 

       <button ng-show="showToEdit" ng-click="mode='edit'" class="my-button">Edit it here</button> 

       <button ng-show="showOnDelete" ng-click="onDelete()(entity)" class="my-button-danger">Delete</button> 
       <button ng-show="showOnUndelete" ng-click="onUndelete()(entity)" class="my-button">Undelete</button> 

       <span> 
        created by <a href="/profile#!/{{entity.createdBy._id}}" class="my-link">{{displayNameCreatedBy}}</a> 
        at {{entity.createdDate}} 
       </span> 
       <span ng-show="showMetaUpdate"> 
        updated by <a href="/profile#!/{{entity.meta.updatedBy._id}}" class="my-link">{{displayNameUpdatedBy}}</a> 
        at {{entity.updatedDate}} 
       </span> 
       <span ng-show="showMetaDelete"> 
        deleted by <a href="/profile#!/{{entity.meta.deletedBy._id}}" class="my-link">{{displayNameDeletedBy}}</a> 
        at {{entity.deletedDate}} 

       </span> 
       <span ng-show="showMetaBan"> 
        banned by <a href="/profile#!/{{entity.meta.bannedBy._id}}" class="my-link">{{entity.meta.displayNameBannedBy._id}}</a> 
        at {{entity.meta.bannedDate}} 
       </span> 

      </div> 
     </div> 
    </div> 


    <!--edit mode--> 
    <div ng-if="showEditMode"> 

     <div class="my-form-group"> 
      <label for="edit_title">Title:</label> 
      <input ng-model="entity.title" id="edit_title" placeholder="Enter Title" class="my-form-control"/> 
     </div> 
     <div class="my-form-group"> 
      <label for="edit_content">Content:</label> 
      <textarea ng-model="entity.content" id="edit_content" class="my-form-control" placeholder="Enter content" class="my-form-control"></textarea> 
     </div> 
     <div ng-show="showOnUpdate" class="my-form-group"> 
      <button ng-click="onUpdate()(entity); mode='view'" class="my-button-success">Update and Done</button> 
     </div> 

    </div> 


    <!--create mode--> 
    <div ng-if="showCreateMode"> 

     <div class="my-form-group"> 
      <label for="create_title">Title:</label> 
      <input ng-model="entityInfo.title" id="create_title" placeholder="Enter Title" class="my-form-control"/> 
     </div> 
     <div class="my-form-group"> 
      <label for="create_content">Content:</label> 
      <textarea ng-model="entityInfo.content" id="create_content" class="my-form-control" placeholder="Enter content" class="form-control"></textarea> 
     </div> 
     <div class="my-form-group"> 
      <button ng-show="showOnCreate" ng-click="onCreate()(entityInfo)" class="my-button-success">Create</button> 
      <button ng-show="showOnCancel" ng-click="onCancel()(entityInfo)" class="my-button">Cancel</button> 
     </div> 

    </div> 

</div> 

Как вы можете видеть, есть 3 div s, view, edit и create , пользователь может переключаться между view и edit режимами. Когда пользователь нажимает кнопку Edit it here, я просто устанавливаю mode = 'edit'. Но пользовательский интерфейс не обновляется.

Я пробовал напрямую, используя <div ng-if="mode === 'view'">, он работает. Но я предпочитаю поставить все переключатели ng-show/hide/if в контроллер в случае усложнения условия

ответ

1

Я попытался сделать что-то подобное в прошлом, но проблема, которую вы видите, это то, что переменные области для отображения режимов (для пример, $scope.showEditMode) не будет автоматически обновляться на основе обновляемой изменяемой переменной ($scope.mode). Вот что делает $watch().

Вы можете создать такую ​​функцию, которая будет обновлять как режим и переменные показывают режим:

$scope.setMode = function(mode) { 
    $scope.mode = mode; 

    $scope.showEditMode = ($scope.mode === 'edit'); 
    $scope.showViewMode = ($scope.mode === 'view'); 
    $scope.showCreateMode = ($scope.mode === 'create'); 
} 

Вы могли бы назвать это от ваших кликов кнопки, как это:

<button ng-show="showToEdit" ng-click="setMode('edit')" class="my-button">Edit it here</button> 

Надежда что помогает. Удачи!

+0

что касается начального режима перед пользователем переключатель? мне нужно сначала вызвать его в контроллере? – OMGPOP

+0

Да, пройдя этот маршрут, вы захотите установить его на нагрузке контроллера. Я изменил функцию на setMode в моем примере, чтобы сделать ее более понятной. Например, вы бы просто заменили там, где вы инициализируете переменные области с помощью $ scope.setMode ('view'). – grdevphl

+0

он работает. очень элегантное решение. – OMGPOP

0

Хорошо так что моя идея будет двигаться всю свою логику в сервис, который возвращает значения, нужно в зависимости от режима, в котором пользователь выбирает

Пример Service

.service('ModeService', function ($http, Ls) { 
    return { 
     ReturnViewValues: function (Mode) { 
     var Obj = {}; 
     if (Mode == 'view') { 
      //put your Controller Logic here 
      Obj.Value1 = your logic 
     } else if (Mode == 'edit') { 
      //put your Controller Logic here 
      Obj.Value1 = your other logic 
     } 
     return Obj; 
    }, 

В вашем контроллере я просто сделать 1 функцию, которая вызывается из всех нг щелкает

$scope.changeMode = function(Mode){ 
    $scope.ViewObj = ModeService.ReturnViewValues(Mode) 
    //now your ViewObj contains all the info you need for the active View 

} 

И в вашем HTML я бы рекомендовал использовать

<button ng-click="changeMode('edit')">Edit</button> 
<button ng-click="changeMode('view')">View</button> 

Я также рекомендовал бы вам создать свой HTML немного более динамичным, так что вам нужно только 1 HTML блок можно использовать нг-класс/и нг щелчки, где вы изменить функциональность в зависимости от режима

Cheers

Смежные вопросы