角UI路由器——在继承状态下的视图。

时间:2021-08-15 11:37:49

edit: Based on the answer by @actor2019 I want to update my question to better explain the problem:

编辑:基于@actor2019的答案,我想更新我的问题,以便更好地解释问题:

Using Angular UI-Router(v0.0.2), I've setup the app to properly navigate between main "pages"/state, while inheriting the base state.

使用角ui -路由器(v0.0.2),我设置了应用程序在主“页面”/状态之间正确导航,同时继承基状态。

Index.html:

index . html:

<div ui-view></div>

base.html:

base.html:

<!-- Header -->
<div>
    <!-- Header markup -->

    <!-- Search View -->
    <div ui-view="search"></div>
</div>

<!-- Page Content view -->
<div ui-view></div>

The issue is here in the app.js file. When I add the views parameter to the base state, everything stops working(100% blank page). Without that parameter, the page renders correctly, but I have no search view.

问题在app.js文件中。当我将视图参数添加到基本状态时,一切都停止工作(100%空白页)。如果没有该参数,页面将显示正确,但是我没有搜索视图。

app.js:

app.js:

$urlRouterProvider.otherwise('/');

//
// Now set up the states
$stateProvider
  .state('base', {
    abstract: true,
    templateUrl: 'views/base.html',
    views: {
      "search": {
        templateUrl: "views/search.html"
      }
    }
  })
  .state('base.home', {
    url: "/",
    templateUrl: "views/home.html"
  })
  .state('base.page2', {
    url: "/page2",
    templateUrl: "views/page2.html"
  });

How do I add views to this parent 'base' state?

如何向父“基”状态添加视图?

角UI路由器——在继承状态下的视图。

UPDATE: The problem with @actor2019's answer here is that the search view gets reinitialized when the state changes. I'd like the views off the base level to persist through state changes.

更新:@actor2019的问题是,当状态改变时,搜索视图会被重新初始化。我希望底层的视图能够通过状态更改来保持。

4 个解决方案

#1


24  

The first obvious mistake:

You can't specify controller and template on the state while your using views. They are mutually exclusive...

在使用视图时,不能在状态上指定控制器和模板。他们是互相排斥的…

This is because when there is no "views" but a controller and template on the state, UI-Router automatically creates the "views" property and pulls those properties to an "empty" view...

这是因为当状态上没有“视图”,只有一个控制器和模板时,UI-Router会自动创建“视图”属性,并将这些属性拉到“空”视图……

.state('base', {
  abstract: true,
  templateUrl: 'views/base.html', //Can't do this
  views: { // when this is there.
    "search": {
      templateUrl: "views/search.html"
    }
  }
})

Instead do:

而不是做的事:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "search": {
        templateUrl: "views/search.html"
      }
    }
  })

Second problem:

How views targeting works with nested views etc. is not very logical, it may work well if you restrict your self to one view in one view all the way down, but ones you start working with multiple named views it all gets confusing... Add unnamed views on top and many people gets lost...

视图目标如何处理嵌套视图等等并不是很合理,如果你一直将自己限制在一个视图中的一个视图中,那么它可能会运行得很好,但是当你开始使用多个命名视图时,它会变得很混乱……在顶部添加未命名的视图,许多人会迷失……

The way views work in UI-Router is the worst part of UI-Router...

视图在UI-Router中的工作方式是UI-Router中最糟糕的部分……

Given you example I am not even entirely sure of the way to target the search view from your abstract parent state... Might be:

举个例子,我甚至不能完全确定从你的抽象的父状态来定位搜索视图的方法……可能是:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "search@base": {
        templateUrl: "views/search.html"
      }
    }
  })

If it can even be made to work... Alternatively you can move the search view out of base.html, but I guess you added it in there for a reason.

如果它能工作……或者你可以把搜索视图移出基地。html,但是我猜你添加它是有原因的。

The whole view concept is the biggest reason why I ended up writing https://github.com/dotJEM/angular-routing instead.

整个视图概念是我最终编写https://github.com/dotJEM/angular-routing的最大原因。

#2


4  

The Child state should be home.search instead of header.search. In your case, you may want to write some abstract state to hold the layout,

儿童国家应该是家。搜索而不是header.search。在你的例子中,你可能想写一些抽象的状态来保存布局,

base.html

base.html

<div class="row-fluid">
    <div class="header">
        <div class="span3" ui-view="logo"></div>
        <div  class="span9" ui-view="menu"></div>
    </div>
</div>

<div class="row-fluid">
    <div class="content">
        <div class="span2" ui-view="sidebar"></div>
        <div  class="span10" ui-view="entry"></div>
    </div>
</div>

in app.js

在app.js

$stateProvider
    .state('base',{
        abstract:true,
        url:'/',
        templateUrl: viewBase+'base.html'
    })
    .state('base.main',{
        url:'',
        views:{
            "logo":{
                templateUrl:viewBase+'main/logo.html'
            },
            "menu":{
                templateUrl:viewBase+'main/menu.html'
            },
            "sidebar":{
                templateUrl:viewBase+'main/sidebar.html'
            },
            "entry":{
                templateUrl: viewBase+'main/entry.html'
            }
        }})

#3


3  

According to the ui-router documentation, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. So, for example, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list". Child states will load their templates into their parent's ui-view. I'd reccomend looking over the section of their documentation entitled Nested States & Views to gain a fuller understanding of how to do this.

根据ui-router文档,当应用程序处于特定状态时——当一个状态是“活动的”时——它的所有祖先状态也都是隐式活动的。例如,当“联系人”。list“状态是活动的,“contacts”状态也是隐式活动的,因为它是“contact .list”的父状态。子状态将把它们的模板加载到父的ui视图中。我将回顾他们的文档中名为嵌套状态和视图的一节,以更全面地了解如何做到这一点。

In the code you have provided us here, the parent state of the search template is home, while

在您提供给我们的代码中,搜索模板的父状态是home。

.state('header.search', {
    templateUrl: "views/search.html",
    controller: "SearchCtrl"
})

implies that the parent state of the search template should be header in order for the view to get loaded correctly. So, I believe the following changes to your app.js will fix your issue.

意味着搜索模板的父状态应该是头,以便正确地加载视图。因此,我相信以下对您的app.js的更改将解决您的问题。

app.js

app.js

$stateProvider
  .state('home', {
    url: "/",
    views: {
      '': {
        templateUrl: "views/mainContent.html",
        controller: "MainCtrl"
      },
      'header': {
        templateUrl: "views/header.html"
      },
      'footer': {
        templateUrl: "views/footer.html"
      },
    }
  })
  .state('home.search', {
    views: {
      'search': {
        templateUrl: "views/search.html",
        controller: "SearchCtrl"
      }
  })
  .state('anotherPage', {
    url: "/anotherPage",
    templateUrl: "views/anotherPage.html"
  });

#4


2  

This works for me.

这适合我。

$stateProvider
    .state('base', {
      abstract: true,
      url:'/',
      templateUrl: 'views/base.html'
    })
    .state('base.home', {
      url: "",
      views: {
      "search@base": {
        templateUrl: "views/searchOfHome.html"
      }
      //content@base, contentOfHome.html
    }
    })
    .state('base.page2', {
      url: "page2",
      views: {
      "search@base": {
        templateUrl: "views/searchOfPage2.html"
      }
      //content@base, contentOfPage2.html
    });

If 'base' is the root state, you don't need the '@base'

如果'base'是根状态,则不需要'@base'

#1


24  

The first obvious mistake:

You can't specify controller and template on the state while your using views. They are mutually exclusive...

在使用视图时,不能在状态上指定控制器和模板。他们是互相排斥的…

This is because when there is no "views" but a controller and template on the state, UI-Router automatically creates the "views" property and pulls those properties to an "empty" view...

这是因为当状态上没有“视图”,只有一个控制器和模板时,UI-Router会自动创建“视图”属性,并将这些属性拉到“空”视图……

.state('base', {
  abstract: true,
  templateUrl: 'views/base.html', //Can't do this
  views: { // when this is there.
    "search": {
      templateUrl: "views/search.html"
    }
  }
})

Instead do:

而不是做的事:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "search": {
        templateUrl: "views/search.html"
      }
    }
  })

Second problem:

How views targeting works with nested views etc. is not very logical, it may work well if you restrict your self to one view in one view all the way down, but ones you start working with multiple named views it all gets confusing... Add unnamed views on top and many people gets lost...

视图目标如何处理嵌套视图等等并不是很合理,如果你一直将自己限制在一个视图中的一个视图中,那么它可能会运行得很好,但是当你开始使用多个命名视图时,它会变得很混乱……在顶部添加未命名的视图,许多人会迷失……

The way views work in UI-Router is the worst part of UI-Router...

视图在UI-Router中的工作方式是UI-Router中最糟糕的部分……

Given you example I am not even entirely sure of the way to target the search view from your abstract parent state... Might be:

举个例子,我甚至不能完全确定从你的抽象的父状态来定位搜索视图的方法……可能是:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "search@base": {
        templateUrl: "views/search.html"
      }
    }
  })

If it can even be made to work... Alternatively you can move the search view out of base.html, but I guess you added it in there for a reason.

如果它能工作……或者你可以把搜索视图移出基地。html,但是我猜你添加它是有原因的。

The whole view concept is the biggest reason why I ended up writing https://github.com/dotJEM/angular-routing instead.

整个视图概念是我最终编写https://github.com/dotJEM/angular-routing的最大原因。

#2


4  

The Child state should be home.search instead of header.search. In your case, you may want to write some abstract state to hold the layout,

儿童国家应该是家。搜索而不是header.search。在你的例子中,你可能想写一些抽象的状态来保存布局,

base.html

base.html

<div class="row-fluid">
    <div class="header">
        <div class="span3" ui-view="logo"></div>
        <div  class="span9" ui-view="menu"></div>
    </div>
</div>

<div class="row-fluid">
    <div class="content">
        <div class="span2" ui-view="sidebar"></div>
        <div  class="span10" ui-view="entry"></div>
    </div>
</div>

in app.js

在app.js

$stateProvider
    .state('base',{
        abstract:true,
        url:'/',
        templateUrl: viewBase+'base.html'
    })
    .state('base.main',{
        url:'',
        views:{
            "logo":{
                templateUrl:viewBase+'main/logo.html'
            },
            "menu":{
                templateUrl:viewBase+'main/menu.html'
            },
            "sidebar":{
                templateUrl:viewBase+'main/sidebar.html'
            },
            "entry":{
                templateUrl: viewBase+'main/entry.html'
            }
        }})

#3


3  

According to the ui-router documentation, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. So, for example, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list". Child states will load their templates into their parent's ui-view. I'd reccomend looking over the section of their documentation entitled Nested States & Views to gain a fuller understanding of how to do this.

根据ui-router文档,当应用程序处于特定状态时——当一个状态是“活动的”时——它的所有祖先状态也都是隐式活动的。例如,当“联系人”。list“状态是活动的,“contacts”状态也是隐式活动的,因为它是“contact .list”的父状态。子状态将把它们的模板加载到父的ui视图中。我将回顾他们的文档中名为嵌套状态和视图的一节,以更全面地了解如何做到这一点。

In the code you have provided us here, the parent state of the search template is home, while

在您提供给我们的代码中,搜索模板的父状态是home。

.state('header.search', {
    templateUrl: "views/search.html",
    controller: "SearchCtrl"
})

implies that the parent state of the search template should be header in order for the view to get loaded correctly. So, I believe the following changes to your app.js will fix your issue.

意味着搜索模板的父状态应该是头,以便正确地加载视图。因此,我相信以下对您的app.js的更改将解决您的问题。

app.js

app.js

$stateProvider
  .state('home', {
    url: "/",
    views: {
      '': {
        templateUrl: "views/mainContent.html",
        controller: "MainCtrl"
      },
      'header': {
        templateUrl: "views/header.html"
      },
      'footer': {
        templateUrl: "views/footer.html"
      },
    }
  })
  .state('home.search', {
    views: {
      'search': {
        templateUrl: "views/search.html",
        controller: "SearchCtrl"
      }
  })
  .state('anotherPage', {
    url: "/anotherPage",
    templateUrl: "views/anotherPage.html"
  });

#4


2  

This works for me.

这适合我。

$stateProvider
    .state('base', {
      abstract: true,
      url:'/',
      templateUrl: 'views/base.html'
    })
    .state('base.home', {
      url: "",
      views: {
      "search@base": {
        templateUrl: "views/searchOfHome.html"
      }
      //content@base, contentOfHome.html
    }
    })
    .state('base.page2', {
      url: "page2",
      views: {
      "search@base": {
        templateUrl: "views/searchOfPage2.html"
      }
      //content@base, contentOfPage2.html
    });

If 'base' is the root state, you don't need the '@base'

如果'base'是根状态,则不需要'@base'