使用 angularjs ui 路由器将 self 部分替换为另一个部分 [英] Replace self partial with another partial with angularjs ui router

查看:28
本文介绍了使用 angularjs ui 路由器将 self 部分替换为另一个部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在客户视图中,我有一个创建客户按钮,它应该加载一个 customers.create.html 部分视图,其中 customers.html 被定位.

如何将当前视图 "customers.html" 替换为另一个视图 "customers.create.html" ?

customers.html

<button ng-click="create()" class="btn btn-default" ui-sref="customers.create">创建</button>

<div style="height:500px;"ng-grid="myOptions"></div>

app.js

$stateProvider.state('客户', {网址:/客户",templateUrl: "../views/customers.html",控制器:['$scope', '$stateParams', '$state',函数($scope,$stateParams,$state){}]}).state('customers.create', {网址:/创建",templateUrl: "../views/customers.create.html"})

在单击创建按钮时,路由更改为/customers/create 而不是 html 视图,它只是保持不变.

我不能将 <div ui-view></div> 放在创建按钮下,因为这样客户数据网格和创建按钮仍然可见.

也许我不应该使用分层的 customers.create 视图?

解决方案

我们需要使用绝对视图名称,以精确地通知 ui-router 在哪里(重新)放置子模板.(查看此示例)在此处阅读更多信息:

引用:

//绝对针对根未命名状态的未命名视图.//

在 index.html 中@":{}

因此,根视图名称是空字符串,对于子视图可以表示为 '@'

$stateProvider.state('客户', {网址:/客户",templateUrl: "../views/customers.html",控制器:['$scope', '$stateParams', '$state',功能($scope,$stateParams,$state){}]}).state('customers.create', {网址:/创建",意见:{'@':{templateUrl: "../views/customers.create.html"}}})

在此plunker

中查看更多信息

扩展.任何状态定义,都定义了视图名称,它的模板/templateUrl/templateProvider 所属的视图名称.如果只有一个模板要注入父 ui-view=""(未命名),我们可以使用以下语法:

.state('客户', {网址:/客户",templateUrl: "tpl.customers.html",控制器: ....})

相当于这个语法:

.state('客户', {网址:/客户",意见:{//我们针对未命名视图的显式信息'':{templateUrl: "tpl.customers.html",控制器: ...}}})

所以,如果我们必须在根级别上ui-view 目标

<div data-ui-view=""></div>

我们可以这样定义状态:

$stateProvider.state('客户', {网址:/客户",意见:{'标题':{模板:'<div>客户</div>',//控制器...},'':{templateUrl: "tpl.customers.html",控制器: ...}}}).state('customers.create', {网址:/创建",意见:{'标题@':{模板:<div>创建</div>",},'@':{templateUrl: "tpl.customers.create.html",}}});

查看扩展示例 plunker

EXTEND:给出评论的答案:

<块引用>

...我不知道为什么它现在在这里工作...和以前一样,我只是把它放在我的代码中:'@':{templateUrl:tpl.customers.create.html",}..

正如这里提到的:查看名称 - 相对名称与绝对名称:

<块引用>

在幕后,每个视图都被分配一个绝对名称,遵循 viewname@statename 方案,其中 viewname 是视图指令中使用的名称和状态名称是状态的绝对名称,例如联系方式.您还可以选择以绝对语法编写视图名称.

那么会发生什么?

  1. 放置在 index.html 中的 ui-view="" 正在获取绝对名称@".其中确实由三部分组成(而只有一个字符).分隔符是@,左边的字符代表viewName,右边的字符代表stateName

  2. 在状态 'customers' 中有一个视图,ui-view="header" 其绝对名称为:header@customers".所以任何子状态都可以使用自己的 tamplate/tempalteUrl/templateProvider

  3. 有一个带有未命名模板的状态 'customers' ui-view="" 其绝对名称将是 "@customers"(@ 的左侧是未命名的空字符串).如果像 'customers.create' 这样的子状态想要定位到这个视图,

它可以使用其中之一:

视图:{@顾客" : {模板: ....}}//或者模板: ....

因为第二个只是使用了隐式符号,最终会以"(没有vie名称)+@"(分隔符)+customers"(parent stateName) == "@customers"

4. 我们可以使用相同的表示法定位根 (index.html).

根名称是"",而视图名称是"",我们以"" + "@" + "" == "@" 结束.这就是为什么这个神奇的设置可以通过 "@"ui-view="" index.html代码>

In the customers view I have a create customer button which should load a customers.create.html partial view where the customers.html is positioned.

How can the current view "customers.html" be replaced by another view "customers.create.html" ?

customers.html

<div>
    <button ng-click="create()" class="btn btn-default" ui-sref="customers.create">Create</button>
</div>
<div style="height:500px;" ng-grid="myOptions"></div>

app.js

$stateProvider
            .state('customers', {
                url: "/customers",
                templateUrl: "../views/customers.html",
                controller:  ['$scope', '$stateParams', '$state',
                    function (  $scope,   $stateParams,   $state){ 
               }]
            })
    .state('customers.create', {
                    url: "/create",
                    templateUrl: "../views/customers.create.html"
                })

At the moment when the create button is clicked the route changes to /customers/create but not the html view it just stays the same.

I can not put the <div ui-view></div> under the create button because then the customers datagrid and the create button would still be visible.

Maybe I should not use a hierarchical customers.create view ?

解决方案

We need to use absolute view name, to precisely inform ui-router, where to (re-)place the child template. (check this example) Read more here:

cite:

// absolutely targets the unnamed view in root unnamed state.
// <div ui-view/> within index.html
"@" : { } 

So, the root view name is empty string, which for a child could be represented as '@'

$stateProvider
  .state('customers', {
      url: "/customers",
      templateUrl: "../views/customers.html",
      controller: ['$scope', '$stateParams', '$state',
        function($scope, $stateParams, $state) {
      }]
  })
  .state('customers.create', {
    url: "/create",
    views: {
      '@': {
        templateUrl: "../views/customers.create.html"
      }
    }
  })

See more here in this plunker

Extend. Any state defintion, is defining the view name, where its template/templateUrl/templateProvider belongs to. If there is only one template to be injected into parent ui-view="" (unnamed) we can use this syntax:

.state('customers', {
      url: "/customers",          
      templateUrl: "tpl.customers.html",
      controller: ....            
  })

which is equal to this syntax:

.state('customers', {
      url: "/customers",
      views: {
        // explicit information that we target unnamed view
        '': {
          templateUrl: "tpl.customers.html",
          controller: ... 
        }
      }
  })

So, if we do have to ui-view targets on the root level

<h4 data-ui-view="header"></h4>
<div data-ui-view=""></div>

we can define states like this:

$stateProvider
  .state('customers', {
      url: "/customers",
      views: {
        'header': {
          template: '<div>customers</div>',
          // controller...
        },
        '': {
          templateUrl: "tpl.customers.html",
          controller: ...
        }
      }
  })
  .state('customers.create', {
    url: "/create",
    views: {
      'header@': {
        template: "<div>create</div>",
      },
      '@': {
        templateUrl: "tpl.customers.create.html",
      }
    }
  })
  ;

See extended example plunker

EXTEND: to give THE answer to a comment:

... I have no idea why it works now here...did the same as before I just put this in my code: '@': { templateUrl: "tpl.customers.create.html", }..

As mentioned here: View Names - Relative vs. Absolute Names:

Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

So what happens?

  1. The ui-view="" placed in index.html is getting the absolute name "@". Which does consist of three parts (while only one char). The delimiter is @, the chars left from it represent the viewName, the chars on a right side represent the stateName

  2. Having in a state 'customers' a view, with ui-view="header" its absolute name would be: "header@customers". So any child state can target this view with its own tamplate/tempalteUrl/templateProvider

  3. Having a state 'customers' with unnamed template ui-view="" its aboslute name would be "@customers" (left side from @ is unnamed empty string). If child state like 'customers.create' would like to target this view,

it can use one of these :

views : {
  "@customers" : {
      template: ....
   }
}
// or
template: ....

because the second just uses implicit notation, which will end up in "" (no vie name) + "@" (delimiter) + "customers" (parent stateName) == "@customers"

4. we can target the root (index.html) using the same notation.

The root name is "" and while the view Name is "" we end up in "" + "@" + "" == "@". And that's why this magical setting does the job to place our view into root ui-view="" index.html via "@"

这篇关于使用 angularjs ui 路由器将 self 部分替换为另一个部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆