AngularJS - CRUD指令/服务/控制器模式

时间:2012-10-15 20:26:30

标签: javascript angularjs

我想在某些方面创建一些与父控制器/作用域交互的指令。我用两种方式做CRUD: A)基于路线,如果您要编辑项目,我使用$ location将URL更改为给定的URL B)基于相同页面,如果你点击一个项目的编辑它从$ scope.tpl设置$ scope.template,那么在部分我有一个ng-hide / show,它隐藏并显示表视图/详细视图。 / p>

我想要实现的可能是在我的指令中使用更少的代码,并且可能使用更基于服务的方法或提示?

指令

'use strict';

/* Directives */
var directives = angular.module("app.directives", ["ui"]);


function CrudCtrl($scope, $attrs, $location, $parse) {
    function getScope(scopeName) {
        scopeName = typeof scopeName || "$parent";
        var ngModel = $parse(scopeName, $scope);
        return ngModel($scope)
    }

    function refreshObjects(scopeName) {
        $scope.svc.query($scope.params, function(objects) {
            var parentScope = getScope(scopeName)
            parentScope.objects = objects
        });
    }

    if (!$scope.refreshObjects) {
        $scope.refreshObjects = function() {
            refreshObjects($attrs.modelname)
        }
    }

    if (!$scope.crudAdd) {
        $scope.crudAdd = function() {
            if ($attrs.url) {
                $location.path($attrs.url);
                return;
            } else {
                var parentScope = getScope($attrs.scope);
                parentScope.object = new $scope.svc();
                parentScope.template = parentScope.tpl;
            }
        }
    }

    if (!$scope.crudDelete) {
        $scope.crudDelete = function() {
            /* Fire off a delete and as a callback we update objects */
            $scope.svc.delete({accountId: $scope.account.uuid, id: $scope.object.id}, function() {
                refreshObjects($attrs.scopeName)
            });
        };
    }

    if (!$scope.crudEdit) {
        $scope.crudEdit = function() {
            if ($attrs.url) {
                $location.path($attrs.url);
                return;
            } else {
                var parentScope = getScope($attrs.scopeName);
                parentScope.object = $scope.object;
                parentScope.template = parentScope.tpl;
            }
        };
    }

    if (!$scope.crudSave) {
        $scope.crudSave = function() {
            var params = {}
            params.accountId = $scope.params.accountId
            if ($scope.object.id) { params.id = $scope.object.id }

            $scope.object.$save(params, function() {
                if ($attrs.url) {
                    $scope.back();
                } else {
                    refreshObjects($attrs.scopeName);

                    var parentScope = getScope($attrs.scopeName);
                    parentScope.template = undefined;
                }
            });
        };
    }

    if (!$scope.crudCancel) {
        $scope.crudCancel = function() {
            if (parentScope.template) {
                var parentScope = getScope($attrs.scopeName);
                parentScope.template = undefined;
            } else {
                $scope.back();
            }
        };
    };
};


directives.directive("refresh", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-primary" ng-click="refreshObjects()"><i class="icon-refresh"></i> Refresh</button>',
    };
});


/* Create something new */
directives.directive("create", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-success" ng-click="crudAdd()"><i class="icon-plus"></i> {{display_text || "Add"}}</button>',
    };
});


/* Delete button and update objects */
directives.directive("delete", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-danger" ng-click="crudDelete()"><i class="icon-remove icon-white"></i> {{display_text}}</button>',
    }
});

/* Helper to create a edit button */
directives.directive("edit", function() {
    return {
        restrict: "E",
        replace:  true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-mini btn-info" ng-click="crudEdit()"><i class="icon-edit"></i> {{display_text || "Edit"}}</a>',
    }
});

/* Save the object and return to the previous page */
directives.directive("save", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn btn-success" ng-click="crudSave()"><i class="icon-ok"> {{display_text || "Save"}}</i></a>',
    };
});

/* Cancel the current action */
directives.directive("cancel", function() {
    return {
        restrict: "E",
        replace: true,
        controller: CrudCtrl,
        scope: true,
        link: function(scope, element, attrs) {
            scope.display_text = attrs.text;
        },
        template: '<button class="btn" ng-click="crudCancel()"><i class="icon-remove"></i> {{display_text || "Cancel"}}</button>'
    }
});

示例控制器

function BookingCtrl($scope, Booking) {
      $scope.svc = Booking;
      $scope.objects = $scope.svc.query($scope.params);
  }

然后在部分概述中我有:

<div ng-hide="template">
<refresh></refresh>
<create url="/{{params.accountId}}/entity/add"></create>

<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th></th>
            <th>Name</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="object in objects">
            <td>
                <delete></delete>
                <edit url="/{{params.accountId}}/category/{{object.resource_id}}"></edit>
            </td>
            <td>{{object.resource_name}}</td>
            <td>{{object.description}}</td>
        </tr>
        </tr>
        </tr>
    </tbody>
</table>
</div>

<ng-show="template" ng-include src="template"></ng-show>

细节部分:

<div class="span4">
    <h3>Category: {{category.resource_name}}</h3>
    <form name="detail_form" class="form-horizontal">
        <div class="control-group">
            <label class="control-label"><strong>Name</strong></label>
            <div class="controls">
                <input required ng-model="object.resource_name" placeholder="Name" type="text" class="input-small">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label"><strong>Description</strong></label>
            <div class="controls">
                <textarea ng-model="object.description" placeholder="Description" type="textarea" rows=5></textarea>
            </div>
        </div>
        <div class="control-group">
            <save scope-name="$parent.$parent"></save>
            <cancel scope-name="$parent.$parent"></cancel>
        </div>
    </form>
<pre>form = {{object | json}}</pre>
</div>

这似乎过分使用$ parent。$ parent如果有更好的解决方法,请帮助我!

1 个答案:

答案 0 :(得分:2)

我会做以下这类功能:

  • $resource投入使用。
  • 使用ng-view绑定网址和部分内容。使用锚点 链接到其他部分。
  • 根据角色定义每个部分的控制器。 (通过服务访问$resource

http://angularjs.org/#wire-up-a-backend可能就是一个例子。