如何从angularjs模块/代码外部调用angularjs$compile?

guykilcj  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(473)

假设我有带有angularjs模块/控制器的html,如下所示:

angular
.module("myModule", [])
.controller("myController", ['$scope', '$compile', function ($scope, $compile) {
    $scope.txt = "<b>SampleTxt</b>";
    $scope.submit = function () {
        var html = $compile($scope.txt)($scope);
        angular.element(document.getElementById("display")).append(html);
    }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myModule" >
    <div ng-controller="myController">
        <form name="myForm">
            <span>Age:</span><input type="number" name="age" ng-model="age"/>
            <textarea ng-model="txt" ></textarea>
            <input type="button" value="submit" ng-click="submit()" />
        </form>
        <div id="display"></div>
    </div>
</body>

上面的示例将允许在运行时使用$compile向angularjs应用程序添加元素。
假设我想插入一个输入元素,如文本框名称 driversLinces 具有属性 ng-required="age > 21" ,假设我想从javascript控制台插入此元素,该元素具有条件必需的特性,以便进行测试和验证。另外,假设我想做同样的事情,但我想修改 ng-required 属性(如果是现有元素,如 age ,我怎么能做到?
我正在考虑创建一个可以访问 $compile 不知怎么的,但不知道怎么做。你能帮助我吗?我只能从控制器内部访问$compile服务。
注意:由于某些限制和缺乏信息/资源,我对完整html代码的访问受到限制。我可以使用ui建模器访问html和angularjs表单。我可以添加我的自定义html代码,但我不知道是否可以将现有的表单部件与我自己的自定义html容器封装在一起,这是添加访问内部部件的指令所必需的。
我可以访问angularjs范围和 ng-form 元素使用 angular.element() . 我可以在表单加载、单击按钮或模型值更改时触发javascript。我可以添加表单元素并将其链接到angularjs模型。我不知道如何从javascript访问$compile服务。

更新:

我将添加更多信息来解释我的目标或用例。我想从javascript向angularjs表单添加自定义验证规则和错误。我正在使用的平台使用angularjs,但不允许我轻松访问angularjs代码来添加指令,或者至少现在,我没有用于此目的的必要资源。但是,这个平台使我能够在点击按钮时触发自定义javascript代码,当表单加载时(加载事件),该按钮会自动触发。此外,我可以传递被单击的按钮的id。有了这个,我可以使用 angular.element('#id').scope() . 这使我能够访问几乎所有其他元素。我能看到所有的东西 ng-modelsng form controllers 以及作用域对象中的所有父对象。有时,我必须访问 $parent 但我认为最终我能够从scope对象访问几乎任何东西。
现在,我需要能够找到表单元素并添加自定义验证规则。我可以遍历scope对象中的所有表单元素,并且我可以找出如何获取元素id及其绑定细节。我现在需要的是如何在表单加载事件中添加自定义验证规则和错误消息。
例如,我可以使用json表示angularjs表单的验证规则,如下所示:

[
    {
        "id": "employee-name",
        "required": true,
        "msg": "Employee name is required."
    },
    {
        "id": "degree",
        "customValidation": "someJSFunctionName",
        "msg": "The provided degree is invalid. Please review the rules and try again."
    }
]

然后,在表单加载事件中,我想将上述规则加载到表单上并使其生效。这怎么可能?考虑到我可以访问范围对象,我只能使用JavaScript,并且我不能使用anguljs指令。

更新2:

根据下面phineasj提供的答案,我使用控制台执行以下命令:

var injector = window.angular.injector(['ng']);
var $compile = injector.get('$compile');
var elm = angular.element("my-element-selector");
var elmScope = elm.scope();
elm.attr('ng-required', true);
var elmCompile = $compile(elm[0])(elmScope);

尽管上面的代码没有抛出任何错误,但是它并没有正常工作。如果我能上场 elm 空的,它不会触发 ng-required 错误,尽管我可以看到 required 属性是在执行 $compile 指挥部。我注意到我必须执行 $compile 每次我更新字段值以便验证规则能够反映时,都会提供服务,但我看不到字段的 ctrl.$error 正在更新的对象。它总是空的。
然后我尝试了以下方法:

var injector = window.angular.injector(['ng', 'myApp']);
var $compile = injector.get('$compile');

... 我弄错了 Uncaught Error: [$injector:unpr] Unknown provider: $rootElementProvider .
然后我尝试了以下方法:

var mockApp = angular.module('mockApp', []).provider({
  $rootElement:function() {
     this.$get = function() {
       return angular.element('<div ng-app></div>');
    };
  }
});
var injector = window.angular.injector(['ng', 'mockApp', 'myApp']);

... 第一次没有抛出错误,但是当我再次尝试时,我得到了错误 The view engine is already initialized and cannot be further extended . 所以我被困在 $compile 服务
我确实尝试过直接使用 $validators() 这是一次成功。详情如下:

//The elm form controller is found on the $parent scope and this is beyond my control.
//The ng-form element names are generated by the back-end and I have no control over this part. In this case the HTML element 'elm' is the form element name 'ewFormControl123'.
elmScope.$parent.ewFormControl123.$validators.required = 
    function (modelValue, viewValue) {
        console.log(modelValue, viewValue);
        var result = !!(modelValue??null);
        console.log("result = ", result);
        return result;
    }

上面的方法看起来确实很好,但是,我仍然对使用它感兴趣 $compile 通过将验证规则或指令注入html代码,然后运行 $compile 服务于该元素。我认为将所需的部分注入html并运行 $compile 这样更好。
我感谢你的帮助。
塔瑞克

hwazgwia

hwazgwia1#

要在angularjs之外调用$compile函数,yon可以使用:

const injector = window.angular.injector(['ng', 'your-module']);
injector.invoke(function($rootScope, $compile) {
  $compile('<div custom-directive></div>')($rootScope);
})

要添加动态验证规则,可以引用自定义验证。这个 controller Scope 也可以从 angular.element().scope 正如你提到的。
下面是一个演示如何动态加载验证器并编译它。https://plnkr.co/edit/4ay3ig2angyjlq92?preview

相关问题