【问题标题】:AngularJs directive which creates new directive with data object insideAngularJs 指令创建新指令,其中包含数据对象
【发布时间】:2016-05-18 10:14:21
【问题描述】:

在我正在开发的应用程序中,用户可以从下拉列表中输入表单类型,并通过单击按钮时调用的指令创建新表单。创建的表单实际上是另一个指令,它被编译到作用域并附加到 DOM 中的包装器元素。这是创建新指令的 click 指令的代码。

(function(){
'use strict';

//on 'add new rule' btn click, a new form is created 

function createRuleForm($compile){

    function linkFn(scope, element, attrs){

        function onClickAddForm(){  

            var type = scope.rcCtrl.ruleType;
            var newDirective = angular.element('<rule-form type="'+type+'"></rule-form>');
            var formWrap = document.querySelector('.edit-rc__div--rf-wrapper');

            angular.element(formWrap).append(newDirective);
            $compile(newDirective)(scope)

        }

        element.bind('click', onClickAddForm)
    }

    return{
        restrict: 'A',
        link: linkFn 
    }   
}

angular.module('ganeshaApp')
.directive('createRuleForm', [
    '$compile',
    createRuleForm
])
})();

创建的每个新表单都有一个隔离范围,因为用户需要能够同时处理多个表单,并保存和编辑这些表单。 “类型”作为属性传递给新表单。这是点击时创建的新指令。

(function(){
'use strict';

function ruleForm(ModalService, CurrentDateService, SaveRule, RULE_PHRASE){

    var index = 0;

    //directive controller
    function RuleFormCtrl($scope, $element, $attrs){

        var rfCtrl = this;

        //values
        rfCtrl.ruleType = $scope.$parent.rcCtrl.ruleType;
        rfCtrl.ruleTitle = 'L_' + $attrs.type + index;
        rfCtrl.phrase = RULE_PHRASE[$attrs.type]    
        rfCtrl.fullDate = CurrentDateService.getCurrentDate()

        //functions
        rfCtrl.saveOneRule = saveOneRule;
        rfCtrl.closeRule = closeRule;

        //saves one rule on click of save button or on timeout
        function saveOneRule(){

        rfCtrl.html = $element.find('.edit-rf__div--textdiv').html();   

            var ruleObject = {
                'index' : index,
                'ruleText' : rfCtrl.ruleText,
                'ruleTitle' : rfCtrl.ruleTitle,
                'ruleType' : rfCtrl.ruleType,
                'typePhrase' : rfCtrl.phrase,
                'html' : rfCtrl.html,
                'fullHtml' : rfCtrl.phrase + rfCtrl.html
            }

            SaveRule.pushRule(ruleObject)
            $scope.ruleForm.$setPristine();
            index++;
        }

        function closeRule(){

            if($scope.ruleForm.$dirty){

                var modal = {
                    "mssg" : 'You have unsaved changes to this rule. Would you like to save them before closing?',
                    "confirm" : 'Yes, please.',
                    "reject" : 'No, thank you.'
                }

                ModalService.openModal(modal).
                then(function(res){
                    console.log(res)
                    saveOneRule();
                    $element.remove();
                }).catch(function(err){
                    console.log(err)
                })
            }else{
                $element.remove();
            }
        }

    }


    return{
        restrict: 'E',
        replace: true,
        scope: {},
        templateUrl: 'modules/edit/edit-create/ruleForm.html',
        controller: RuleFormCtrl,
        controllerAs: 'rfCtrl'
    };

}

angular.module('ganeshaApp')
.directive('ruleForm', [
    'ModalService',
    'CurrentDateService',
    'SaveRule',
    'RULE_PHRASE',
    ruleForm
]);

})();

当一个表单被保存时,它被添加到视图中的一个可滚动列表中。

对于第一次创建和保存表单,这里一切正常。我遇到的困难是当用户需要从视图中的表单列表中打开一个表单时。与创建传递给新指令的数据是简单字符串“ruleType”的新表单不同,为已完成的表单创建指令需要将保存的对象数据传递给新指令。

我只是想知道是否有人对单击指令创建需要与数据打包的元素指令的这种情况有任何经验?

【问题讨论】:

  • 这对我来说不太合适,但我不确定我是否完全理解。你为什么不直接使用 data 和 ng-repeat 来驱动你的表单输入和绑定,而不是动态地编译呢?如果你有一个 plunkr/fiddle 我可以仔细看看它或提出更好的方法
  • 感谢您的回复,丹尼尔。我很抱歉,因为解释起来有点混乱。我考虑过使用 ng-repeat,但它似乎不太适合这个用例。用户想要查看他们正在处理的“规则”列表(这是视图中的 ng-repeat 可滚动列表),但他们可能只想一次编辑一个,或者可能两个......基本上他们想要随时控制他们的视图..但是现在考虑一下,也许过滤器会提供解决方案。我会看看我以后能不能弄个小提琴。
  • 太好了,如果你这样做,请在这里打我,我会看看。根据您的评论,我会使用过滤器来控制它。随着您扩展解决方案,沿着上述道路前进会变得相当混乱

标签: javascript angularjs angularjs-directive angularjs-scope


【解决方案1】:

您应该能够在编译元素时将数据添加到您的范围,然后在您的 html 中引用它

var type = scope.rcCtrl.ruleType;

var data = {'your': 'data', 'object': 'here'};

//add the data to the scope so that the child element has access to it
scope.data = data;

//pass the data into your rule-form directive using whatever attribute you declared 
var newDirective = angular.element('<rule-form type="'+type+'" form-data="data"></rule-form>');
var formWrap = document.querySelector('.edit-rc__div--rf-wrapper');

angular.element(formWrap).append(newDirective);
$compile(newDirective)(scope)

只需确保您的规则表单指令的范围正在寻找该表单数据属性

return{
    restrict: 'E',
    replace: true,
    scope: {
        formData: '='
    },
    templateUrl: 'modules/edit/edit-create/ruleForm.html',
    controller: RuleFormCtrl,
    controllerAs: 'rfCtrl'
};

然后在RuleFormCtrl中,可以访问formData

function RuleFormCtrl($scope...){
    var data = $scope.formData;
}

【讨论】:

  • 谢谢,抽搐!它工作正常,但我不得不做一些小的修改。如果对象是正在编译元素的指令中的 scope.rcCtrl.data,我必须在新指令中使用 $scope.$parent.rcCtrl.data 访问它,因为范围是隔离的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2014-03-21
  • 1970-01-01
  • 2012-09-19
  • 2014-02-14
  • 1970-01-01
相关资源
最近更新 更多