问题 AngularDart可以直接路由到组件吗?


我正在使用AngularDart和路由。我的观点是包含单个组件的单行。我觉得这些观点没有重视。我可以直接路由到组件吗?


例:

router.root
  ..addRoute(
      name: 'welcome',
      path: '/welcome',
      defaultRoute: true,
      enter: view('views/welcome.html'))
  ..addRoute(
      name: 'camera',
      path: '/camera',
      enter: view('views/camera.html'));

而且这里 views/welcome.html

<welcome></welcome>

而且这里 views/camera.html

<camera></camera>

如您所见,这些观点相当薄弱。我更喜欢说:“当你进入视图时,插入这个组件”

那可能吗?


11703
2018-01-10 23:31


起源



答案:


我想问同样的问题,但你是第一个!我找到了一个解决方案,可能不是最好的解决方案,但至少它有效。

我为所有路线创建了一个html:

dyn_view.html:

<div><dynamic-view></dynamic-view></div>

当然还有一个组件动态视图,它从路由提供程序获取实际组件标记名称,并使用此处描述的技术动态添加到DOM: 如何在Angular.Dart中以编程方式添加组件?

dynamic_view.html

<div></div>

dynamic_view.dart

@NgComponent(
    selector: 'dynamic-view',
    templateUrl: 'view/dynamic_view.html'
)
class DynamicView implements NgShadowRootAware {
  Compiler compiler;
  Injector injector;
  String elementName;

  DynamicView(this.compiler, this.injector, RouteProvider provider) {  
    elementName = provider.parameters["elementName"];
  }

  void onShadowRoot(ShadowRoot shadowRoot) {
    DivElement inner = shadowRoot.querySelector("div");
    inner.appendHtml("<$elementName></$elementName>");    
    BlockFactory template = compiler(inner.nodes);
    var block = template(injector);
    inner.replaceWith(block.elements[0]); 
  }
}

现在的路由器。必须以某种方式将元素名称传递给RouteProvider。我受到这篇文章的启发: 在加载控制器之前验证路由前提条件

class DynamicViewFactory {
  ViewFactory viewFactory;
  DynamicViewFactory(this.viewFactory);

  call(String elementName) {
     return (RouteEvent event) {
       event.parameters["elementName"] = elementName;
       viewFactory("view/dyn_view.html")(event);
     };
  }
}



class MyRouteInitializer implements RouteInitializer {

  init(Router router, ViewFactory view) {
    DynamicViewFactory dynView = new DynamicViewFactory(view);
    router.root
      ..addRoute(
          name: 'route1',
          path: '/a/:b',
          enter: dynView('componentA'))
      ..addRoute(
          name: 'route2',
          path: '/b/:c',
          enter: dynView('componentB'));
  }
}

上面的代码稍微修改了我实际使用的内容,所以它可能有一些小错误,但总体思路是一样的。

希望有所帮助!


4
2018-01-15 17:33



凉!我想知道你是否可以将它作为酒吧套餐运送,以便我和其他人可以使用它。如果你发布它,请告诉我。 - Seth Ladd
你的模块看起来如何?我没有将我的RouteProvider注入到DynamicView中。 - Seth Ladd
我的应用程序基于Angular教程: github.com/angular/angular.dart.tutorial/tree/master/Chapter_06。该模块看起来像:'MyModule类扩展Module {MyModule(){type(QueryService);类型(DynamicView); //组件类型(ApplicationComponent);键入(ScreenComponent); ... type(RouteInitializer,implementedBy:MyRouteInitializer); factory(NgRoutingUsePushState,(_)=> new NgRoutingUsePushState.value(false)); }}' - Michal Pietrusinski
现在添加了一些功能,另一个答案更好。 - Scotty Waggoner


答案:


我想问同样的问题,但你是第一个!我找到了一个解决方案,可能不是最好的解决方案,但至少它有效。

我为所有路线创建了一个html:

dyn_view.html:

<div><dynamic-view></dynamic-view></div>

当然还有一个组件动态视图,它从路由提供程序获取实际组件标记名称,并使用此处描述的技术动态添加到DOM: 如何在Angular.Dart中以编程方式添加组件?

dynamic_view.html

<div></div>

dynamic_view.dart

@NgComponent(
    selector: 'dynamic-view',
    templateUrl: 'view/dynamic_view.html'
)
class DynamicView implements NgShadowRootAware {
  Compiler compiler;
  Injector injector;
  String elementName;

  DynamicView(this.compiler, this.injector, RouteProvider provider) {  
    elementName = provider.parameters["elementName"];
  }

  void onShadowRoot(ShadowRoot shadowRoot) {
    DivElement inner = shadowRoot.querySelector("div");
    inner.appendHtml("<$elementName></$elementName>");    
    BlockFactory template = compiler(inner.nodes);
    var block = template(injector);
    inner.replaceWith(block.elements[0]); 
  }
}

现在的路由器。必须以某种方式将元素名称传递给RouteProvider。我受到这篇文章的启发: 在加载控制器之前验证路由前提条件

class DynamicViewFactory {
  ViewFactory viewFactory;
  DynamicViewFactory(this.viewFactory);

  call(String elementName) {
     return (RouteEvent event) {
       event.parameters["elementName"] = elementName;
       viewFactory("view/dyn_view.html")(event);
     };
  }
}



class MyRouteInitializer implements RouteInitializer {

  init(Router router, ViewFactory view) {
    DynamicViewFactory dynView = new DynamicViewFactory(view);
    router.root
      ..addRoute(
          name: 'route1',
          path: '/a/:b',
          enter: dynView('componentA'))
      ..addRoute(
          name: 'route2',
          path: '/b/:c',
          enter: dynView('componentB'));
  }
}

上面的代码稍微修改了我实际使用的内容,所以它可能有一些小错误,但总体思路是一样的。

希望有所帮助!


4
2018-01-15 17:33



凉!我想知道你是否可以将它作为酒吧套餐运送,以便我和其他人可以使用它。如果你发布它,请告诉我。 - Seth Ladd
你的模块看起来如何?我没有将我的RouteProvider注入到DynamicView中。 - Seth Ladd
我的应用程序基于Angular教程: github.com/angular/angular.dart.tutorial/tree/master/Chapter_06。该模块看起来像:'MyModule类扩展Module {MyModule(){type(QueryService);类型(DynamicView); //组件类型(ApplicationComponent);键入(ScreenComponent); ... type(RouteInitializer,implementedBy:MyRouteInitializer); factory(NgRoutingUsePushState,(_)=> new NgRoutingUsePushState.value(false)); }}' - Michal Pietrusinski
现在添加了一些功能,另一个答案更好。 - Scotty Waggoner


这似乎现在直接支持

看到 https://github.com/angular/angular.dart/issues/425

您可以路由到内联模板(viewHtml):

views.configure({
  'foo': ngRoute(
      path: '/foo',
      viewHtml: '<foo-component></foo-component>')
});

6
2018-04-18 06:32