【问题标题】:Check if file exists for ng-include in $routeProvider template检查 $routeProvider 模板中的 ng-include 文件是否存在
【发布时间】:2015-06-16 13:26:56
【问题描述】:

我已经设置了我的 Angular 路由以使用 URL 中的 slug 来确定要加载的文件。它看起来像这样:

$routeProvider.when("/project/:slug", { 
  controller: "ProjectController",
  template: function($routeParams){ 
    return '<div id="project" ng-include="\'/views/' + $routeParams.slug + '.html\'"></div>'; 
  }
});

很有魅力,但如果ng-include 的文件不存在,这里就没有备用方案。我考虑过使用解析,但我似乎无法正确检查文件。我的尝试如下所示:

$routeProvider.when("/project/:slug", { 
  controller: "ProjectController",
  resolve: {
    check: ["$route", "$http", "$location", function($route, $http, $location){
      $http.get("/views/" + $route.current.params.slug + ".html").then(function(res){
        if (!res.data) $location.path("/");
        else return true;
      });
    });
  },
  template: function($routeParams){ 
   return '<div id="project" ng-include="\'/views/' + $routeParams.slug + '.html\'"></div>'; 
  }
});

值得注意的是,这是 MEAN 堆栈上的单页应用程序的一部分。我在 NodeJS 中的 Express 路由设置如下:

app.get("*", function(req, res){ res.sendFile(__dirname + "/public/index.html"); });

【问题讨论】:

    标签: javascript html angularjs node.js routes


    【解决方案1】:

    原来问题是因为我在 NodeJS 中将所有文件请求路由到我的 index.html。因此,当我尝试调用 $http 来检查 .html 视图是否存在时,它总是返回 index.html,因此返回 true。 Node中的解决方法如下:

    app.use(express.static(__dirname + "/public", { maxAge: 86400000 }));
    app.get("/framework/*",function(req,res){ res.sendFile(__dirname + "/public" + req.path); });
    app.get("/views/*",function(req,res){ res.sendFile(__dirname + "/public" + req.path); });
    app.get("*", function(req, res){ res.sendFile(__dirname + "/public/index.html"); });
    

    然后我可以像这样在我的 Angular 路由中使用解析:

    $routeProvider.when("/projects/:slug", { 
      controller: "ProjectController",
      resolve: {
        check: ["$route", "$http", "$location", function($route, $http, $location){
          return $http.get("/views/" + $route.current.params.slug + ".html").success(function(res){
            return true;
          }).error(function(res){
            return $location.path("/");
          });
        }]
      },
      template: function($routeParams){ 
        return '<div id="project" ng-include="\'/views/' + $routeParams.slug + '.html\'"></div>'; 
      }
    });
    

    所以这个问题是特定于单页应用程序设置的。

    【讨论】:

      【解决方案2】:

      你可以从 resolve 函数中返回一个 Promise。您的示例当前触发请求,然后返回 undefined

      我没有测试以下内容,但它应该返回一个承诺。 (当请求失败或响应中的data 属性为假时,此承诺将失败。

      $routeProvider.when("/project/:slug", { 
        controller: "ProjectController",
        resolve: {
          check: ["$route", "$http", "$q", function($route, $http, $q){
            return $http.get("/views/" + $route.current.params.slug + ".html")
                  .then(function(res){
                      if (!res.data) {
                          return $q.reject('No data');
                      }
                      return $q.resolve('Found');
                  });
          }];
        },
        template: function($routeParams){ 
         return '<div id="project" ng-include="\'/views/' + $routeParams.slug + '.html\'"></div>'; 
        }
      });
      

      对于承诺被拒绝的情况。 (请求失败或没有数据)您可以订阅$routeChangeError事件来处理这种情况,并将浏览器定位到/路由。

      【讨论】:

      • 谢谢,但我发现问题出在我的问题中的最后一个代码 sn-p - 单页应用程序路由。对 NodeJS 路由的更改解决了这个问题。我已经在下面回答了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      相关资源
      最近更新 更多