【问题标题】:How to load data attributes in AngularJS functions?如何在 AngularJS 函数中加载数据属性?
【发布时间】:2015-01-23 15:06:37
【问题描述】:

我正在玩一个同时使用 JQuery 和 AngularJS 的网站项目。 $http 用于浏览器和服务器之间的 REST 通信。该网站的网址是localhost:8080/myproject。因此,每个页面或资源都有一个路径/myproject/someresource。为了能够轻松构建这些路径,我在bodyelement 上使用了一个数据属性:

<!DOCTYPE html>
<html>
...
<body data-url="myproject">
</body>

data-url 的实际值是通过 JSP 的&lt;c:url value="/" /&gt; 动态生成的。现在我想使用这个属性为$http 方法构建一些路径。为此,我使用了 JQuery:

var path = $('body').attr('data-url');

但是,我必须等待 DOM 生成结束,所以前一个被包装:

var path;
$(function() {
    path = $('body').attr('data-url');
}

另一方面,我有一个用于按钮的 AngularJS $scope 函数:

<button ng-click="foo()">click</button>

...

var mainApp = angular.module('main', [ 'ngResource' ]);
mainApp.controller('myController', function($scope, $http) {
  $scope.foo = function() {
    $http.get(path + 'folder').success(function(response) { /* do crazy stuff */ });
  };
}

为了使 Angular 代码的编译能够正常工作,它可能不会像 path 的定义那样包含在 $ 函数中。因此,path 不会在控制器定义时设置。我发现的唯一解决方案是将foo() 的定义移动到$() 中并将$http 存储在$scope 中:

mainApp.controller('myController', function($scope, $http) {
  $scope.$http = $http;
}
$(function() {
    var path = $('body').attr('data-url');
    var $scope = angular.element($('main')).scope();
    var $http = $scope.$http;

    $scope.foo = function() {
      $http.get(path + 'folder').success(function(response) { /* do crazy stuff */ });
    };
}

这个问题有什么干净的解决方案吗?我的方式看起来像一个肮脏的黑客......

【问题讨论】:

  • 你不能简单地使用&lt;base href="..." /&gt;标签吗?
  • 你能解释一下为什么需要在data-url中动态加载路径吗?如果不需要以这种方式加载它,您可以使用“普通”AngularJS 进行静态配置...
  • @sp00m 我可以使用这个标签。但这并不能解决 AngularJS 的控制器需要在完成 DOM 设置之前定义的主要问题,而这又需要在我可以通过 JQuery 查询属性之前完成。
  • @arman1991 那么您是否将myproject 硬编码到Javascript 代码中?如果是这样,我希望此值取决于某些属性,该属性可能会在顶部文件夹名称更改时由构建系统自动更改。如果您知道如何配置它,请拍摄。
  • @Bastian,我在AngularJS中发布了基本的路由配置,希望它能推动你前进......

标签: jquery angularjs url custom-data-attribute


【解决方案1】:

你可以在 angularjs 中使用全局变量

首先,设置变量

app.run(function ($rootScope) {
    $rootScope.path = $('body').attr('data-url');
});

终于

var mainApp = angular.module('main', [ 'ngResource' ]);
mainApp.controller('myController', function($scope, $http) {
  var path = $scope.path;
  $scope.foo = function() {
    $http.get(path + 'folder').success(function(response) { /* do crazy stuff */ });
  };
}

干杯!

【讨论】:

  • 您的解决方案有效,但是,它没有解决最初的问题 - 请参阅我的答案了解详情
【解决方案2】:

好吧,真丢脸——我不知道为什么 AngularJS 和 JQuery 的执行顺序会出现问题,但它们似乎已经消失了。当我写这篇文章时,我认为 AngularJS 的编译是在加载 JQuery 之前执行的,这就是为什么我不能在我的控制器定义中使用 JQuery。也许我把什么弄混了……

但是,我刚刚检查了安迪的回答,发现他的解决方案可行。尽管如此。我可以跳过他建议的全局变量的使用,只需将我所有的控制器逻辑直接放入控制器定义中——包括 JQuery 调用:

var mainApp = angular.module('main', [ 'ngResource' ]);
mainApp.controller('myController', function($scope, $http) {
  $scope.foo = function() {
    var path = $('body').attr('data-url');
    $http.get(path + 'folder').success(function(response) { /* do crazy stuff */ });
  };
});

这是有道理的,因为 AngularJS 内部已经使用了 JQuery (jqLite)...

【讨论】:

    【解决方案3】:

    您可以使用$routeProvider 配置路由并使用constants 保存您的URL,然后将其注入模块中。

    angular
        .module('app', ['ngRoute'])
        .constant("myConfig", {
            "url": "http://localhost",
            "port": "8080"
        })
        .config(function ($routeProvider) {
            $routeProvider
                .when('/somesource', { 
                    templateUrl: 'views/page.html',
                    controller: 'myController'
                })
                .when('/somesource2', { 
                    templateUrl: 'views/page2.html',
                    controller: 'myController2'
                })
                .otherwise({
                    redirectTo: '/'
                });
        })
        .controller('myController', function (myConfig) {
            // Your functions...
        });
    

    这是可以在应用程序的任何部分注入配置的示例。 通过这种方式,您可以为每个路径管理页面的 url 以及哪个控制器将用于该路径...

    也许这个解决方案对你有帮助。

    【讨论】:

      猜你喜欢
      • 2017-12-17
      • 1970-01-01
      • 2018-06-12
      • 2017-11-16
      • 2015-07-30
      • 2016-03-11
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      相关资源
      最近更新 更多