通用HTML / JavaScript部件的不同指令 - 最佳实践

时间:2015-10-21 14:28:26

标签: angularjs angularjs-directive

在我的应用程序中,我可以通过创建指令来创建新表单。这些指令/表格可以配置为我网站上的某些部分使用。

现在所有这些表单都应该有两个按钮来保存/取消所有更改。因此,每个表单都有一个(微风)DataContext和这些按钮及其事件处理程序。

我想做的是"继承"用于按钮的HTML和用于事件处理程序(和DataContext)的JavaScript代码,并且还能够覆盖/扩展事件处理程序,以便在必要时以具体形式执行其他操作。

这样做的最佳做法是什么?我想到了以下方法,但它们似乎不太实用:

  • 创建一个" Base" -Directive,它可以转换配置的具体表单指令。这意味着,当我想使用其中一个表单时,我将不得不使用" Base" -Directive并将其配置为使用具体表单。
  • 在我的" Concrete" -Directive中,使用" Base" -Directive添加功能。这意味着,要覆盖其中一个事件处理程序,我需要知道JavaScript中的指令 - 这并不容易("要求"只能在父方向上工作)。

我还考虑过将$ scope或controller作为一个属性传递给一个或另一个,并使用一个服务来"初始化"所有指令'带有处理函数的$ scopes。但这似乎有点脏。

对我来说最好的解决方案是,如果我可以直接使用任何表单指令,而不必考虑按钮等。当我创建一个新的表单指令时,我可以告诉它什么到& #34;继承"从而且如果我需要在"保存"中做一些特别的事情。或者"取消"事件处理程序,能够覆盖它。

这有可能吗?

1 个答案:

答案 0 :(得分:1)

这是一个在示例中调用saveForm方法的小例子。此方法使用指令侦听由任何事件触发的save-form

<强> JS

(function(){
    'use strict';    
    angular
        .module("myApp", [])
        .directive("saveButton", [function () {
         return {
             restrict: 'E',
             scope: {},
             template: "<input type='button' value='Save' />",
             link: function(scope) {
                 //expose the method to the outside world
                 scope.saveForm = saveForm;

                 //listen to the broadcast
                scope.$on("save-form", function () {
                  scope.saveForm();
                });

             }
         }

         function saveForm() {
             alert("Now I am saving");
         }
        }]);

    angular
        .module("myApp")
        .controller("myController", myController);

    //inject $scope to call $broadcast
    myController.$inject = ["$scope"];

    function myController($scope) {
        var vm = this;
        vm.text = "Save will be triggered on blur...";

        vm.doSave = function() {
            $scope.$broadcast("save-form");
        }
    }
})();

查看

<div ng-app="myApp">
    <div ng-controller="myController as vm">
        <form>

            <save-button ng-click='vm.doSave()'></save-button>
            <input type="text" value="{{ vm.text }}" ng-blur="vm.doSave()" />
        </form>
    </div>
</div>

JSFiddle http://jsfiddle.net/hescano/k7yjkvk6/

现在,如果您的表单以不同的方式保存,您可以为您的指令提供保存该特定表单所需的方法:

<强> JS

(function(){
    'use strict';    
    angular
        .module("myApp", [])
        .directive("saveButton", [function () {
         return {
             restrict: 'E',
             scope: {
                mySaveFunction: "="
             },
             template: "<input type='button' value='Save' />",
             link: function(scope) {
                 //expose the method to the outside world     
                 //listen to the broadcast
                scope.$on("save-form", function () {
                    if(typeof scope.mySaveFunction === "function")
                    {
                        scope.mySaveFunction.call();
                    }
                });

             }
         }
        }]);

    angular
        .module("myApp")
        .controller("myController", myController);

    //inject $scope to call $broadcast
    myController.$inject = ["$scope"];

    function myController($scope) {
        var vm = this;
        vm.text = "Save will be triggered on blur...";

        vm.doSave = function() {
            $scope.$broadcast("save-form");
        }

        vm.thisFormsSave = function() {
            alert("I save the way I want!");
        }
    }
})();

查看

<div ng-app="myApp">
    <div ng-controller="myController as vm">
        <form>

            <save-button ng-click='vm.doSave()' my-save-function="vm.thisFormsSave"></save-button>
            <input type="text" value="{{ vm.text }}" ng-blur="vm.doSave()" />
        </form>
    </div>
</div>

请注意,这样我在文本框中没有任何更改,并且仍然使用新功能保存。

JSFiddle http://jsfiddle.net/hescano/k7yjkvk6/1/