从子组件访问最多父控制器

时间:2017-08-08 20:46:02

标签: angularjs angularjs-scope angular-components angular1.6

我在我的应用程序中使用了angular 1.5组件,这是我的结构:

<body ng-app ng-controller="appController as app">
    <div ui-view="home">
        <home-component>
            {{ app.user }}
        </home-component>
    </div>
</body> 

基本上,我将ui-router与Angular组件一起用于嵌套视图。

我知道,使用controller as语法,您可以访问父控制器,但由于某种原因,我不能。 {{ app.user }}

没有显示任何内容

现在我已经读过,组件的范围是孤立的,但我认为这只是意味着父组件无法访问子组件。

如果完全隔离,我将如何访问父控制器中的全局数据?

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用requires在子组件中创建对它的引用。

这种语法基本上可以在任何地方找到它:

<script src="app.js"></script>


<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, intitial-scale = 1" />
  <link rel="stylesheet" href="style.css" />
  <title>Weather</title>
  <link href="https://fonts.googleapis.com/css?family=Monoton" rel="stylesheet">
  <script src=h ttps://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js></script>
</head>



<body>
  <header>
    <h1>
      <div id="temp"></div>
      <div id="minutely" id="tempunit"></div>
    </h1>
    <h2>
      <div id="location"></div>
    </h2>
  </header>
  <p><span id="city" </span><span id="country"></span></p>
  <button class="btn btn-primary" id="BT1">Change Metric</button>

</body>

或者这个语法只会为组件查找一个作为父语句:

require: {
      app: '^homeComponent'
    }

然后在子组件中,您可以通过app属性引用homeComponent。

您还可以通过使用?添加引用来使引用成为可选项。像:

require: {
      app: '^^homeComponent'
    }

答案 1 :(得分:1)

使用require property访问父控制器和地图 绑定到子组件的控制器:

app.component("homeComponent", {
  require: {main: "^ngController"},
  template: 
    `<fieldset>
      <h3>home-component</h3>
      <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
    </fieldSet>`
})

以上示例绑定到ng-controller directive的控制器。

来自文档:

  

组件间通信

     

指令可以require其他指令的控制器以实现彼此之间的通信。这可以通过为require属性提供对象映射来在组件中实现。对象键指定属性名称,在该属性名称下,所需的控制器(对象值)将绑定到需要组件的控制器。

     

— AngularJS Developer Guide - Components (Intercomponent Communication)

The DEMO

&#13;
&#13;
angular.module("app",[])
.component("homeComponent", {
  require: {main: "^ngController"},
  template: 
    `<fieldset>
      <h3>home-component</h3>
      <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
    </fieldSet>`
})
.controller("appController", function() {
  var main = this;
  main.user = "someUser";
})
&#13;
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app" ng-controller="appController as main">
      <h2>Main App</h2>
      <input ng-model="main.user" />
      <br><br>
      <home-component>
      </home-component>
  </body> 
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如果指令被隔离,最好传递参数需要使用的任何值,否则为什么要将它隔离?

import io.github.jhipster.config.JHipsterConstants;
import io.github.jhipster.config.JHipsterProperties;
import io.github.jhipster.web.filter.CachingHttpHeadersFilter;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.servlet.InstrumentedFilter;
import com.codahale.metrics.servlets.MetricsServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.*;
import org.springframework.boot.web.embedded.undertow.*;//.UndertowEmbeddedServletContainerFactory;
import io.undertow.UndertowOptions;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.io.File;
import java.nio.file.Paths;
import java.util.*;
import javax.servlet.*;

/**
 * Configuration of web application with Servlet 3.0 APIs.
 */
@Configuration
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {

    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);

    private final Environment env;

    private final JHipsterProperties jHipsterProperties;

    private MetricRegistry metricRegistry;

    public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {

        this.env = env;
        this.jHipsterProperties = jHipsterProperties;
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        if (env.getActiveProfiles().length != 0) {
            log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
        }
        EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
        initMetrics(servletContext, disps);
        if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
            initCachingHttpHeadersFilter(servletContext, disps);
        }
        if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
            initH2Console(servletContext);
        }
        log.info("Web application fully configured");
    }

    /**
     * Customize the Servlet engine: Mime types, the document root, the cache.
     */
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
        mappings.add("html", "text/html;charset=utf-8");
        // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
        mappings.add("json", "text/html;charset=utf-8");
        container.setMimeMappings(mappings);
        // When running in an IDE or with ./gradlew bootRun, set location of the static web assets.
        setLocationForStaticAssets(container);

        /*
         * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
         * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
         * See the JHipsterProperties class and your application-*.yml configuration files
         * for more information.
         */
        if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
            container instanceof UndertowEmbeddedServletContainerFactory) {

            ((UndertowEmbeddedServletContainerFactory) container)
                .addBuilderCustomizers(builder ->
                    builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
        }
    }

    private void setLocationForStaticAssets(ConfigurableEmbeddedServletContainer container) {
        File root;
        String prefixPath = resolvePathPrefix();
        root = new File(prefixPath + "build/www/");
        if (root.exists() && root.isDirectory()) {
            container.setDocumentRoot(root);
        }
    }

    /**
     *  Resolve path prefix to static resources.
     */
    private String resolvePathPrefix() {
        String fullExecutablePath = this.getClass().getResource("").getPath();
        String rootPath = Paths.get(".").toUri().normalize().getPath();
        String extractedPath = fullExecutablePath.replace(rootPath, "");
        int extractionEndIndex = extractedPath.indexOf("build/");
        if(extractionEndIndex <= 0) {
            return "";
        }
        return extractedPath.substring(0, extractionEndIndex);
    }

    /**
     * Initializes the caching HTTP Headers Filter.
     */
    private void initCachingHttpHeadersFilter(ServletContext servletContext,
                                              EnumSet<DispatcherType> disps) {
        log.debug("Registering Caching HTTP Headers Filter");
        FilterRegistration.Dynamic cachingHttpHeadersFilter =
            servletContext.addFilter("cachingHttpHeadersFilter",
                new CachingHttpHeadersFilter(jHipsterProperties));

        cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*");
        cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*");
        cachingHttpHeadersFilter.setAsyncSupported(true);
    }

    /**
     * Initializes Metrics.
     */
    private void initMetrics(ServletContext servletContext, EnumSet<DispatcherType> disps) {
        log.debug("Initializing Metrics registries");
        servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
            metricRegistry);
        servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
            metricRegistry);

        log.debug("Registering Metrics Filter");
        FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
            new InstrumentedFilter());

        metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
        metricsFilter.setAsyncSupported(true);

        log.debug("Registering Metrics Servlet");
        ServletRegistration.Dynamic metricsAdminServlet =
            servletContext.addServlet("metricsServlet", new MetricsServlet());

        metricsAdminServlet.addMapping("/management/metrics/*");
        metricsAdminServlet.setAsyncSupported(true);
        metricsAdminServlet.setLoadOnStartup(2);
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = jHipsterProperties.getCors();
        if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
            log.debug("Registering CORS filter");
            source.registerCorsConfiguration("/api/**", config);
            source.registerCorsConfiguration("/v2/api-docs", config);
        }
        return new CorsFilter(source);
    }

    /**
     * Initializes H2 console.
     */
    private void initH2Console(ServletContext servletContext) {
        log.debug("Initialize H2 console");
        ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", new org.h2.server.web.WebServlet());
        h2ConsoleServlet.addMapping("/h2-console/*");
        h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/");
        h2ConsoleServlet.setLoadOnStartup(1);
    }

    @Autowired(required = false)
    public void setMetricRegistry(MetricRegistry metricRegistry) {
        this.metricRegistry = metricRegistry;
    }
}

如果不需要在子指令

中使用,您可以转换内容
<home-component user="app.user"></home-component>

.directive('homeComponent', function() {
  return {
    scope: { user: '=' },
    ...
  }
})