角度自定义指令ng-show双向绑定无法正常工作

时间:2015-07-09 12:06:20

标签: angularjs angularjs-directive

我有一个tag-comment自定义指令。它有3种模式:vieweditcreate

这是我对tag-comment的控制器功能:

    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个divvieweditcreate。用户可以在viewedit模式之间切换。当用户点击Edit it here按钮时,我只需设置mode = 'edit'即可。但UI未更新。

我已尝试直接使用<div ng-if="mode === 'view'">,它有效。但我更喜欢将所有ng-show/hide/if切换放在控制器中以防条件变得更复杂

2 个答案:

答案 0 :(得分: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>

希望有所帮助。祝你好运!

答案 1 :(得分:0)

好的,我的想法是将所有逻辑移动到一个服务中,根据用户选择的模式返回所需的值

示例服务

.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;
    },

在你的控制器中,我只需制作一个从所有ng-clicks调用的函数

$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块就可以使用ng-class /和ng-clicks来改变功能,具体取决于模式

干杯

相关问题