Javascript AngularJS使用路由参数实现客户端包含的方法是什么?

Javascript AngularJS使用路由参数实现客户端包含的方法是什么?,javascript,html,angularjs,angular-ui-router,angularjs-routing,Javascript,Html,Angularjs,Angular Ui Router,Angularjs Routing,假设我的AngularJS应用程序中有两个页面,一个显示作者的信息,另一个显示书籍的信息。我有一个单独的模板文件、控制器和路由。在作者页面上,我想显示有关他最近写的书的信息。我该怎么做 我的每条路线都嵌入了一个URL参数,该参数告诉控制器要为哪个作者或书籍获取数据: .when('/authors/:authorId', { templateUrl: 'author.html', controller: 'AuthorsController') .when('/books/:bookId', {

假设我的AngularJS应用程序中有两个页面,一个显示作者的信息,另一个显示书籍的信息。我有一个单独的模板文件、控制器和路由。在作者页面上,我想显示有关他最近写的书的信息。我该怎么做

我的每条路线都嵌入了一个URL参数,该参数告诉控制器要为哪个作者或书籍获取数据:

.when('/authors/:authorId', { templateUrl: 'author.html', controller: 'AuthorsController')
.when('/books/:bookId', { templateUrl: 'book.html', controller: 'BooksController')
据我所知,我不能使用
ng include
,因为它不支持路由参数,只支持模板文件。我可以使用带有
src=“/books/”
IFrame,但它感觉应该有一种角度的方式来使用URL参数进行客户端包含。我阅读了
uirouter
的wiki页面,但这只涵盖了URL请求的接收端

ng view
似乎也不是正确的解决方案,因为我已经在
index.html
格式模板中使用了它。下面是我要显示的HTML的逻辑结构:

<html ng-app="myApp">
    <body>
        <!-- displays template from the current route, e.g. /authors/1 -->
        <div data-ng-view>
            <!-- this HTML is loaded from the author.html template -->
            Author: George R. R. Martin
            (other author details...)

            Most recent book:
            *** THIS IS MY PROBLEM -- HOW TO INCLUDE /books/1 ? ***

                <!-- this HTML is loaded from the book.html template -->
                Title: A Dance with Dragons
                Pub. date: 2011
                ...
        </div>
    </body>
</html>
author.html
中的代码片段:

Author: {{author.name}}
Most recent book:
    <!-- all I'm trying to do is to include HTML from a route, but ng-include doesn't support using routes :( -->
    <div ng-include='/books/{{mostRecentBookId}}'></div>


All books:
    <!-- this is where @Akeem's solution breaks down; the knowledge of which bookId to include comes from the HTML below, not the AuthorsController -->
    <div ng-repeat="bookId in allBooks">
        <div ng-include='/books/{{bookId}}'></div>
        <br/>
    </div>
作者:{{Author.name}
最近出版的书:
所有书籍:

编辑
我已经将@Akeem建议的解决方案应用到我的示例中,并添加了关于为什么它对我不起作用的注释:

据我所知,尽管ng include创建了一个新的作用域,但它也从其父作用域继承了变量。因此,您可以在AuthorsController中设置
$scope.bookId
,并在BooksController中检查此变量

app.controller('AuthorsController', function($scope) {
  $scope.bookId = 123;
});

app.controller('BooksController', function($scope,$routeParams) {
  if(!$scope.bookId){
    $scope.bookId= $routeParams['bookId'];
  }
  var books = {'1' : 'To Killing a Mockingbird', '23' : 'Harry Potter', '123':'Catch 22'};
  $scope.title = books[$scope.bookId];
});
从那里,您可以将ng include指令与ng controller指令结合起来,在author.html模板中使用BooksController

<div ng-include src='"books.html"' ng-controller='BooksController'></div>

最后,在books.html中,您可以正常引用所有变量

<h1>{{title}}</h1>
<p>This is a book with an id of {{bookId}}</p>
<hr>
{{title}
这是一本id为{{bookId}的书



好的,我从@Akeem的解决方案中找到了缺失的部分:。我已经更新了我的应用程序来使用它,它很有效。以下是如何包含另一个模板,使用ng init设置
$scope.bookId
变量,而不是使用路由参数:

<div ng-init="bookId = author.mostRecentBook" ng-include="'book.html'"></div>
这样做的缺点是调用代码与它包含的模板文件更紧密地耦合,而不是使用路由URL作为抽象层。被调用的控制器需要检查scope和route参数,以查看哪个参数用于传入
bookId

.controller('BooksController', function($scope, $routeParams) {
    if (!$scope.bookId) {
        $scope.bookId = $routeParams['bookId'];
    }
    ...
})
我的偏好是通过我设置的路径(
“/books/:bookId”
)找到一种方法来包含书籍数据,但由于似乎没有这样做的方法,因此必须结合使用
ng repeat
ng init


值得思考的是:可能角度路由并不用于包含单个部分,而仅用于包含每页的单个
ng视图
模板。但是我打赌你可以创建一个如下的指令:

<div ng-include-url="/books/1"></div>


它在
$route
服务中查找URL,并且ng是否包括使用路由的
templateUrl
(和
controller
)属性。在传递给控制器之前,它还必须从
$routeParams
对象中的URL设置
bookId
。我既没有时间也没有勇气去完成这件事,但是,使用我已经配置的路由将内容从一个模板/控制器动态加载到另一个模板/控制器似乎很有用。

根据格式,我猜您需要一个图书id来显示图书的详细信息,而在作者页面上您没有任何图书id,对吗?因此,即使您需要显示最新书籍的详细信息,那么您发送作者详细信息的web服务也必须至少向您发送作者最新书籍的bookid。您的书籍模板文件是特定于每本书的html?啊,您可以使用共享范围来传达要显示的
bookid
,而不是使用路由参数!这肯定会解决我的问题。但是,我发现它有一个问题:它在
AuthorsController
BooksController
之间引入了耦合。如果我想在作者的页面上展示两本最新的书呢?那么
BooksController
如何知道在每种情况下显示哪本书呢?@SteveK在这种情况下,您很可能会使用ng repeat和bookIds列表。从这里开始,您将在bookList中拥有
bookId,并应用相同的代码。好的,如果我显示一个简单的书籍列表,这将起作用,因为我可以将
bookId
分配给
ng repeat
循环中的单个书籍。但是,如果我想先显示
mostRecentBookId
的书籍详细信息,然后再迭代接下来的其他书籍,该怎么办?在
author.html
的源代码中,我正在执行
book.html
ng include
,要显示的图书ID来自不同的
$scope
变量:
mostRecentBookId
bookId
(来自
ng repeat
)。我更新了我的问题以解决这个用例。
.controller('BooksController', function($scope, $routeParams) {
    if (!$scope.bookId) {
        $scope.bookId = $routeParams['bookId'];
    }
    ...
})
<div ng-include-url="/books/1"></div>