为什么$render从不接到电话

Why $render never gets call

本文关键字:电话 render 为什么      更新时间:2023-09-26

我有以下代码片段。

<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
    <title>CustomForms</title>
    <script src="angular.js"></script>
    <link href="bootstrap.css" rel="stylesheet" />
    <link href="bootstrap-theme.css" rel="stylesheet" />
    <script type="text/ng-template" id="triTemplate">
        <div class="well">
            <div class="btn-group">
                <button class="btn btn-default">Yes</button>
                <button class="btn btn-default">No</button>
                <button class="btn btn-default">Not Sure</button>
            </div>
        </div>
    </script>
    <script>
        angular.module("exampleApp", [])
        .controller("defaultCtrl", function ($scope) {
            $scope.dataValue = "Not Sure";
        })
        .directive("triButton", function () {
            return {
                restrict: "E",
                replace: true,
                require: "ngModel",
                template: document.querySelector("#triTemplate").outerText,
                link: function (scope, element, attrs, ctrl) {
                    element.on("click", function (event) {
                        setSelected(event.target.innerText);
                        scope.$apply(function () {
                            ctrl.$setViewValue(event.target.innerText);
                        });
                    });
                    var setSelected = function (value) {
                        var buttons = element.find("button");
                        buttons.removeClass("btn-primary");
                        for (var i = 0; i < buttons.length; i++) {
                            if (buttons.eq(i).text() == value) {
                                buttons.eq(i).addClass("btn-primary");
                            } 
                        }
                    }
                    ctrl.$render = function () {
                        console.log("render");
                        setSelected(ctrl.$viewValue || "Not Sure");
                    }
                }

            }
        });
    </script>
</head>
<body ng-controller="defaultCtrl">
    <div><tri-button ng-model="dataValue"/></div>
    <div class="well">
            Value:
            <select ng-model="dataValue">
                <option>Yes</option>
                <option>No</option>
                <option>Not Sure</option>
            </select>
    </div>
</body>
</html>

当我更改选择选项的值时,ctrl.$render 被调用,但为什么当我单击按钮时,ctrl.$render 永远不会被调用?

$viewValue具有与模型不同的值时,才会调用$render。在您的情况下,当调用$setViewValue时,它将首先设置$viewValue,然后将模型设置为相同的值。因为$viewValue是先更新的,所以当 AngularJS 获取模型更改时,它会看到$viewValue具有相同的值,因此不会调用$render

如果要调用$render,请像@SoluableNonagon指出的那样强制调用它,或者修改单击处理程序以更改模型而不是调用$setViewValue。这是演示后一种方法的 plunkr:http://plnkr.co/edit/uAqSxsAd49FkXa5Yu5Vs?p=preview。相关的代码段是:

var ngModelSet = $parse(attrs.ngModel).assign                    
element.on("click", function (event) {
    setSelected(event.target.innerText);
    scope.$apply(function () {
      ngModelSet(scope, event.target.innerText)
    })
});

强制它怎么样?为什么不在单击事件中调用呈现函数?

element.on("click", function (event) {
    setSelected(event.target.innerText);
    scope.$apply(function () {
        ctrl.$setViewValue(event.target.innerText);
    });
    ctrl.$render();
});