首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从外部调用AngularJS $compile模块/代码?

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

Stack Overflow用户
提问于 2021-05-31 17:57:41
回答 2查看 256关注 0票数 1

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

代码语言:javascript
运行
复制
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);
    }
}]);
代码语言:javascript
运行
复制
<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>

上面的示例允许在运行时使用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模型。我不知道如何从$compile访问JavaScript服务。

更新:

我将添加更多的信息来解释我的目标或用例。我希望从AngularJS表单中从JavaScript中添加自定义验证规则和错误。我所使用的平台使用AngularJS,但不允许我轻松地访问AngularJS代码来添加指令,或者至少在目前,我没有为此目的所需的资源。但是,这个平台为我提供了在单击按钮时触发自定义JavaScript代码的能力,该按钮可以在表单加载时自动触发( on事件)。另外,我还可以传递单击按钮的ID。有了这个功能,我就可以使用angular.element('#id').scope()访问范围了。这使我能够访问几乎所有其他元素。我可以在作用域对象中看到所有的ng-modelsng form controllers及其所有父级。有时,我必须访问$parent才能到达根,但我认为最终我能够访问范围对象中的几乎任何东西。

现在,我需要能够找到表单元素并添加自定义验证规则。我可以遍历范围对象中的所有表单元素,并且可以知道如何获取元素ID及其绑定细节。我现在所需要的就是如何在表单加载事件上添加一个自定义验证规则和错误消息。

例如,我可以使用JSON表示AngularJS表单的验证规则,如下所示:

代码语言:javascript
运行
复制
[
    {
        "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."
    }
]

然后,在表单加载事件上,我希望将上述规则加载到表单上,并使它们生效。这怎麽可能?考虑到我可以访问scope对象,我只能使用JavaScript,而不能使用AngularJS指令。

更新2:

根据下面PhineasJ提供的答案,我使用了控制台和以下命令:

代码语言:javascript
运行
复制
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错误,尽管我可以看到在执行$compile命令之后添加了required属性。我注意到每次更新字段值时都必须执行$compile服务,以使验证规则反映出来,但我没有看到字段的ctrl.$error对象正在更新。它总是空的。

然后我尝试了以下几点:

代码语言:javascript
运行
复制
var injector = window.angular.injector(['ng', 'myApp']);
var $compile = injector.get('$compile');

..。我得到了错误Uncaught Error: [$injector:unpr] Unknown provider: $rootElementProvider

然后我尝试了以下几点:

代码语言:javascript
运行
复制
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()添加规则,这是成功的。详情见下文:

代码语言:javascript
运行
复制
//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更好。

更新3

在@PhineasJ的帮助下,我成功地准备了一个使用AngularJS injector$compile服务的小示例。这是成功的,但同样的方法不适用于目标应用程序。

w3school原始示例:吴-要求

JS Fiddle示例:https://jsfiddle.net/tarekahf/5gfy01k2/

按照这个方法,只要有一个选择器来抓取元素,我就可以在运行时为任何字段加载验证规则。

现在,当我在目标应用程序上应用相同的方法时,我遇到了一些错误。我有两个问题:

  1. 如果我在应用程序名中使用const injector = angular.injector(['ng', 'myApp']),则会得到错误:Uncaught Error: [$injector:unpr] Unknown provider: $rootElementProvider
  2. 如果我不添加应用程序名,则不会引发错误,但验证规则不受尊重。

但是,如果我使用formController.$validators对象,我可以添加验证规则,并且它是受尊重的。我不知道为何没有人建议这样做。

我感谢你的帮助和反馈。

更新4

我找到了解决办法。检查我在下面添加的答案。

塔里克

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-03 20:42:24

修复方法是使用以下命令获取注入器:

var injector = angular.element("#myAngularAppID").injector();

其中myAngularAppID id定义了ng-app元素的元素ID。

注入器语句的下列变体不起作用:

代码语言:javascript
运行
复制
//Without using the app
var injector = window.angular.injector(['ng']);
//With the app
var injector = window.angular.injector(['ng', 'myApp'])

一旦实施上述修正,问题就得到了解决。

特别感谢@PhineasJ。此外,下列参考资料也帮助了我:

  1. 注射器返回未定义的值?
  2. angularjs编译ng控制器及插补

检查possible,它具有使用$compile动态添加AngularJS元素并将它们绑定到AngularJS作用域的所有可能的变体:

https://jsfiddle.net/tarekahf/5gfy01k2/

票数 1
EN

Stack Overflow用户

发布于 2021-07-23 08:09:12

要在$compile之外调用AngularJS函数,您可以使用:

代码语言:javascript
运行
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67778393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档