0

我正在尝试找到一个更好的解决方案来ui-routerangular components.

考虑两个简单的组件:

app.component('componentOne', {
  template: '<h1>My name is {{$ctrl.name}}, I am {{$ctrl.age}} years old.</h1>',
  bindings : {
      name : '@',
      age : '@'
    }
  }
);

app.component('componentTwo', {
  template: '<h1>I am component 2</h1>'
});

现在,我正在使用template属性指定组件及其参数:

 app.config(function($stateProvider, $urlRouterProvider ){
 $stateProvider
    .state('component1', {
      url: "/component1",
      template: "<component-one name=\"foo\" age=\"40\"></component-one>"
    })
    .state('component2', {
      url: "/component2",
      template: "<component-two></component-two>"
    })
});

虽然这工作正常,但我的组件有十个绑定,这使得配置非常ui-router 尴尬

我尝试使用该component属性,但这对我根本不起作用。我发现的唯一其他解决方案是使用require属性指定父级并省略绑定 - 但这对我来说感觉不合适......有没有更好的方法来做到这一点?

这是一个plnkr

4

3 回答 3

1

或者,您可以将绑定向下移动一个级别并创建一个对象,该对象将是唯一的绑定。如果 10 个绑定是困扰您的问题。

于 2016-07-31T07:27:52.173 回答
1

您可以尝试的一种替代方法是通过$stateChangeStart事件状态的自定义属性覆盖模板。

像这样运行块来实现这种行为。

app.run(function($rootScope){

    //listen to $stateChangeStart
    $rootScope.$on("$stateChangeStart",function(event, toState, toParams, fromState, fromParams, options){

    //if the component attribute is set, override the template
    if(toState.component){


      //create element based on the component name
      var ele = angular.element(document.createElement(camelCaseToDash(toState.component)));

      //if there is any binding, add them to the element's attributes.
      if(toState.componentBindings){
        angular.forEach(toState.componentBindings,function(value,key){
          ele.attr(key,value)
        })
      }

      //you may also do something like getting bindings from toParams here

      //override the template of state
      toState.template = ele[0].outerHTML;
    }


  })

  //convert camel case string to dash case
  function camelCaseToDash(name) {
    return name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  }

})

现在有了这个,你可以component在你的状态配置中拥有属性。

app.config(function($stateProvider, $urlRouterProvider ){
 $stateProvider
    .state('component1', {
      url: "/component1",
      component:"componentOne",
      componentBindings:{
        name:"foo",
        age:"40",
      }
    })
    .state('component2', {
      url: "/component2",
      component:"componentTwo",
    })
});

这是正在工作的plunker

你仍然可能有一个很大的配置函数,但它看起来并不那么尴尬。

于 2016-08-11T12:30:11.347 回答
1

UI-Routercomponent:路由存在于 UI-Router 1.0+(目前为 1.0.0-beta.1)

这是一个更新的 plunker:https ://plnkr.co/edit/VwhnAvE7uNnvCkrrZ72z?p=preview

绑定静态值

要将静态数据绑定到组件,请使用component和返回静态数据的解析块。

$stateProvider.state('component1', {
  url: "/component1",
  component: 'componentOne', 
  resolve: { name: () => 'foo', age: () => 40 }
})

绑定异步值

要绑定异步值,请使用返回数据承诺的解析。请注意,一个解析可以依赖于不同的解析:

$stateProvider.state('component1Async', {
  url: "/component1Async",
  component: "componentOne",
  resolve: {
    data: ($http) => $http.get('asyncFooData.json').then(resp => resp.data),
    name: (data) => data.name,
    age: (data) => data.age
  }
});

绑定很多值

您提到您在一个组件上有 10 个绑定。根据您要绑定的数据的结构,您可以使用 JavaScript 来构建resolve块(毕竟它是“只是 javascript”)

var component2State = {
  name: 'component2',
  url: '/component2',
  component: 'componentTwo',
  resolve: {
    data: ($http) => $http.get('asyncBarData.json').then(resp => resp.data)
  }
}

function addResolve(key) {
  component2State.resolve[key] = ((data) => data[key]);
}

['foo', 'bar', 'baz', 'qux', 'quux'].forEach(addResolve);

$stateProvider.state(component2State);
于 2016-08-15T16:29:33.380 回答