检查$ routeProvider模板中是否存在ng-include文件

时间:2015-06-16 13:26:57

标签: javascript html angularjs node.js routes

我已设置我的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的文件不存在,则不会有回退。我想过使用resolve,但我似乎无法正确检查文件。我的尝试看起来像这样:

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

2 个答案:

答案 0 :(得分: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路由中使用resolve,如下所示:

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

因此,此问题特定于单页面应用程序设置。

答案 1 :(得分:0)

您可以从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事件来处理该情况并将浏览器定位到/路由。