角度ng-click功能需要两次点击才能生效

时间:2016-07-20 02:28:28

标签: angularjs angular-ui-bootstrap

我有以下指令

app.directive('replybox', function ($timeout, $window, $compile, $sce) {
    var linkFn = function (scope, element, attrs) {


        var exampleText= element.find('p');
        var btn = element.find('button');

        var windowSelection="";

        scope.okOrCancel="None";

        exampleText.bind("mouseup", function () {
            scope.sel = window.getSelection().toString();
            windowSelection=window.getSelection().getRangeAt(0);
            if(scope.sel.length>0) {      
                scope.showModal = true;
                scope.$apply();
            }
        });


        btn.bind("click", function () {

            if(scope.okOrCancel=='ok'){
                range = windowSelection;
                var replaceText = range.toString();
                range.deleteContents();
                var div = document.createElement("div");
                div.innerHTML = '<poper><a href=""  popover-trigger="mouseenter" uib-popover="'+scope.selection+'">' + replaceText + '</a><button type="button" class="btn btn-danger btn-xs">&times;</button></poper>';
                var frag = document.createDocumentFragment(), child;
                while ((child = div.firstChild)) {
                    frag.appendChild(child);
                }
                $compile(frag)(scope);
                range.insertNode(frag);
                scope.showModal=false;
            } 

            if(scope.okOrCancel=='cancel'){
                scope.showModal=false;
            }

            scope.selection="None";
            scope.okOrCancel='None';
        });



    };
    return {
        link: linkFn,
        restrict: 'A',
        scope: {
            entities: '=',
            selection:'='
        },

        template: `<ng-transclude></ng-transclude>
                    <div class="modal fade in" style="display: block;" role="dialog" ng-show="showModal"> 
                        <div class="modal-dialog"> 
                            <div class="modal-content">
                                <div class="modal-body">
                                    {{sel}}
                                </div>  
                                <div class="radio">
                                    <div ng-repeat="x in entities">
                                        <div class="radio">
                                            <label>
                                                <input type="radio" name="choice" ng-model="$parent.selection" ng-value = "x">
                                                    {{x}} 
                                            </label>
                                        </div>
                                    </div>
                                </div>   
                                <div class="modal-footer"> 
                                    <button type="button" class="btn btn-primary" ng-click="okOrCancel='ok'">
                                        Ok
                                    </button> 
                                    <button type="button" class="btn btn-primary" ng-click="okOrCancel='cancel'">
                                        Cancel
                                    </button> 
                                </div> 
                            </div> 
                        </div> 
                    </div>`,
        transclude: true
    };
});

因此模板中有一个模态,其中包含&#34; Ok&#34;和&#34;取消&#34;按钮。这些按钮上有一个ng-click,可将scope.okOrCancel设置为适当的值。 btn绑定按钮单击并根据scope.okOrCancel的状态执行不同的操作。当&#34; Ok&#34;点击按钮一切按预期工作。但是&#34;取消&#34;按钮需要两次单击才能使模态消失。我认为这会立即发生在

if(scope.okOrCancel=='cancel'){
      scope.showModal=false;
}

任何人都可以告诉我为什么取消按钮需要两次点击才能关闭模态?

2 个答案:

答案 0 :(得分:2)

目前,您可以使用jQuery和angularjs混合使用ok和取消点击。可能这是需要两次点击才能生效的原因。

如果我是你,我会点击如下点击:

模板:

<div class="modal-footer"> 
    <button type="button" class="btn btn-primary" ng-click="okClick()"> Ok </button>
    <button type="button" class="btn btn-primary" ng-click="cancelClick()"> Cancel </button>
</div>

在JS中:

scope.okClick = function() {
    range = windowSelection;
    var replaceText = range.toString();
    range.deleteContents();
    var div = document.createElement("div");
    div.innerHTML = '<poper><a href=""  popover-trigger="mouseenter" uib-popover="'+scope.selection+'">' + replaceText + '</a><button type="button" class="btn btn-danger btn-xs">&times;</button></poper>';
    var frag = document.createDocumentFragment(), child;
        while ((child = div.firstChild)) {
            frag.appendChild(child);
        }
    $compile(frag)(scope);
    range.insertNode(frag);
    scope.showModal=false;
} 

scope.cancelClick = function() {
    scope.showModal=false;
}

scope.selection="None";
scope.okOrCancel='None';

我希望这可以帮到你!

干杯

答案 1 :(得分:1)

完全同意varit05的回答。很可能是因为您没有在click事件处理程序中触发摘要循环。但无论如何,重点是:混合jquery和有角度的东西并不是一个好主意,除非:a)你绝对确定它是必要的; b)你很了解你在做什么以及为什么;否则会导致这种意想不到的后果。

另一个小小的补充。另一个问题是:

$compile(frag)(scope);
range.insertNode(frag);

正确的方法实际上是将新节点插入到真正的DOM中,然后再将$ compile()插入它们。否则,在插入的DOM中具有require: "^something"的任何指令将无法编译,因为它们将无法在上节点中找到必要的控制器,直到新节点实际进入“主”DOM树。当然,如果你完全确定你没有,那么你可以保持原样并且它会起作用......但是问题只会在那里等待它的“最好的时刻”。