用angularjs ui路由器替换另一部分的自我部分

Eli*_*eth 4 angularjs angular-ui-router

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

如何将当前视图"customers.html"替换为另一个视图"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>
Run Code Online (Sandbox Code Playgroud)

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"
                })
Run Code Online (Sandbox Code Playgroud)

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

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

也许我不应该使用分层客户.创建视图?

Rad*_*ler 6

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

引用:

// absolutely targets the unnamed view in root unnamed state.
// <div ui-view/> within index.html
"@" : { } 
Run Code Online (Sandbox Code Playgroud)

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

$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"
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)

点击此处了解更多信息

延伸.任何状态定义都是定义视图名称,其template/templateUrl/templateProvider属于该名称.如果只有一个模板要注入父ui-view =""(未命名),我们可以使用以下语法:

.state('customers', {
      url: "/customers",          
      templateUrl: "tpl.customers.html",
      controller: ....            
  })
Run Code Online (Sandbox Code Playgroud)

这等于这个语法:

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

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

<h4 data-ui-view="header"></h4>
<div data-ui-view=""></div>
Run Code Online (Sandbox Code Playgroud)

我们可以定义这样的状态:

$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",
      }
    }
  })
  ;
Run Code Online (Sandbox Code Playgroud)

请参阅扩展示例plunker

EXTEND:给出评论的答案:

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

如上所述:视图名称 - 相对与绝对名称:

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

那会发生什么?

  1. ui-view=""摆在index.html越来越绝对名称"@".它由三部分组成(只有一个字符).分隔符是@,它左边的字符代表viewName,右边的字符代表stateName

  2. 在状态中'customers'具有ui-view="header"绝对名称的视图将是:"header@customers".因此,任何子状态都可以使用自己的tamplate/tempalteUrl/templateProvider来定位此视图

  3. 拥有一个'customers'具有未命名模板的状态,ui-view=""其aboslute名称将是"@customers"(@的左侧是未命名的空字符串).如果孩子状态喜欢'customers.create'以此视图为目标,

它可以使用以下其中一种:

views : {
  "@customers" : {
      template: ....
   }
}
// or
template: ....
Run Code Online (Sandbox Code Playgroud)

因为第二个只使用隐式表示法,最终会以"" (没有名字) +"@" (分隔符) +"customers" (父状态名称) =="@customers"结束

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

根名称是"",而视图名称是"",我们最终进入"" + "@" + "" == "@".这就是为什么这个神奇的设置能够将我们的视图放入root ui-view=""index.html via"@"