javascript - $(document).AngularJS 的现成替代方案

标签 javascript jquery html angularjs gentelella

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

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

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

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

custom.min.js 的片段

$(document).ready(function () {
  init_sparklines(), init_flot_chart(), init_sidebar(), init_wysiwyg(), init_InputMask(), ...
});

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';

})

提前致谢!

最佳答案

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

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

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

举个例子:我猜你的 init_flot_chart()在 DOM 中向下爬行,寻找一个特定的元素,它将在其中绘制一个 float 图表。代替自上而下的方法,创建一个指令:

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
      }
    };
});

你可以这样使用:

<flot-wrapper data="{{theChartData}}"></flot-wrapper>

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

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

(请注意,如果 theChartData 的内容发生变化,这不会自动更新;可以看到一个更详细的例子,它也会监视变化并做出适当的响应 here。)

关于javascript - $(document).AngularJS 的现成替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43782270/

相关文章:

javascript - 我如何设置一个方法来更新 JavaScript 对象传递的属性?

javascript - 当屏幕最大化时,div 模式弹出窗口在 IE 上无法正确呈现,在 Chrome 上工作正常

javascript - 使用 jquery 循环播放视频

javascript - 回溯历史后 Firefox 中的 Ajax 调用缓存

javascript - Jquery 多次点击

javascript - Bootstrap 导航栏下拉框不显示下拉菜单

javascript - jquery加载后在新窗口中按id附加innerHTML

jquery - 如何在 wordpress 中使用主页面和子页面显示可自定义的菜单?

jquery - 在不裁剪的情况下缩放 iFrame/对象

html - Ruby inside html-erb 文件问题