$(document).ready 替代 AngularJS

Jér*_*émy 3 html javascript jquery angularjs gentelella

我正在使用一个名为 Gentelella 的模板,我正在尝试在其中实现 AngularJS。但是,我遇到了某个 Javascript 文件的问题。在该文件的末尾,$(document).ready调用了一个函数来初始化 Javascript 代码,从而对 HTML 代码进行一些更改。问题是该$(document).ready函数在 HTML 完全加载之前被调用得太早。

出现这个问题可能是因为我使用了 ngRoute,这会将模板 html 文件注入到 index.html 的 ng-view 中。发生这种情况时,DOM 可能已经在 AngularJS 注入模板 (=HTML) 之前宣布准备好文档。

所以基本上,一旦 AngularJS 注入模板,我只需要找到一种方法来调用 Javascript 文件中的一些代码。

我附上了一些代码来深入了解这个问题:

custom.min.js 的片段

$(document).ready(function () {
  init_sparklines(), init_flot_chart(), init_sidebar(), init_wysiwyg(), init_InputMask(), ...
});
Run Code Online (Sandbox Code Playgroud)

main.js 的片段:

.config(function($routeProvider, $httpProvider) {

  $routeProvider.when('/', {
    templateUrl : 'dash.html',
    controller : 'dash',
    controllerAs: 'controller'
  }).when('/login', {
    templateUrl : 'login.html',
    controller : 'navigation',
    controllerAs: 'controller'
  }).when('/plain_page', {
    templateUrl : 'plain_page.html',
    controller : 'dash',
    controllerAs: 'controller'
  }).otherwise('/');

  $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';

})
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Dan*_*eck 5

许多 jQuery 插件依赖于 1. 绘制 DOM 的工作流程。2. 运行一个init()函数来针对这些 DOM 元素设置代码。

该工作流程在 Angular 中表现不佳,因为 DOM 不是静态的:Angular 在其自己的生命周期中设置和销毁 DOM 节点,这可能会覆盖事件绑定或在 Angular 之外进行的 DOM 更改。当您使用 Angular 时,文档就绪并不是特别有用,因为它表明 Angular 本身已准备好开始运行。

要有效地使用 Angular,您必须养成仅在实际需要时才启动代码的习惯。因此init_foo(); init_bar();,您应该拥有一个带有自己的 init 代码的 Foo 指令和一个带有自己特定的 init 代码的 Bar 指令,而不是一大堆on document.ready,等等。这些指令中的每一个都应该只修改由该特定指令创建的 DOM。这是确保您需要修改的 DOM 元素实际存在的唯一安全方法,并且您不会在指令之间创建冲突或意外的相互依赖关系。

举一个例子:我猜你会init_flot_chart()在 DOM 中爬行,寻找一个特定的元素,它会在其中绘制一个浮图。而不是那种自上而下的方法,创建一个指令:

angular.module('yourApp')
  .directive('flotWrapper', function () {
    return {
      template: "<div></div>",
      scope: {
        data: '@'
      },
      link: function(scope, elem, attrs) {
        var options = {}; // or could pass this in as an attribute if desired
        $.plot(elem, scope.data, options); // <-- this calls flot on the directive's element; no DOM crawling necessary
      }
    };
});
Run Code Online (Sandbox Code Playgroud)

你像这样使用:

<flot-wrapper data="{{theChartData}}"></flot-wrapper>
Run Code Online (Sandbox Code Playgroud)

... wheretheChartData是一个包含要在图表中绘制的任何数据的对象。(您可以添加其他属性以传入您喜欢的任何其他参数,例如浮动选项、标题等)

当 Angular 绘制该 flotWrapper 指令时,它首先在指令模板中创建 DOM 元素,然后link针对模板的根元素运行其函数中的任何内容。(flot 库本身可以通过一个普通的旧<script>标签包含在内,因此它的plot功能在指令需要时可用。)

(请注意,如果内容发生theChartData变化,这不会自动更新;可以在此处看到一个更详细的示例,该示例还可以监视更改并做出适当的响应。)