Jerry's Blog

Recording what I learned everyday

View on GitHub


11 July 2019

Angular (27) -- Angular Modules

by Jerry Zhang

LeetCode Day 6: P100. Same Tree (Easy)

题目

检查两个二叉树是否完全相同

我的思路:

递归,检测两棵树本身的值相等,并且左右子树是否完全相同

我的算法:

如果两个节点都是空,就是相等的。

如果两个节点其中之一是空,就是不等的。

如果都不是空的,就要检测本身的值和其子树的值。

我的代码:

public class E_100_SameTree {
    public static boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if (p == null || q == null) {
            return false;
        }
        return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

    public static void main(String[] args) {
        TreeNode p = new TreeNode(1);
        p.left = new TreeNode(2);
        p.right = new TreeNode(1);

        TreeNode q = new TreeNode(1);
        q.left = new TreeNode(1);
        q.right = new TreeNode(2);

        System.out.println(isSameTree(p, q));
    }
}

又击败了100%的其他用户。。。

最优解法:(跟我的差不多)

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p == null && q == null){
            return true;
        }
        if((p!= null && q == null) || (p==null && q!=null)){
            return false;            
        }
        if(p.val != q.val){
            return false;
        }
        if(!isSameTree(p.left, q.left)){
           return false; 
        }
        if(!isSameTree(p.right, q.right)){
            return false;
        }
        return true;
    }
}

坑:

一开始我没考虑其中一个是null的情况,出现了空指针异常。

所以以后关于树的问题,要的null的各类情况尽量考虑全。

Angular

Angular Modules

AppModule contains:

  1. Components
  2. Directives
  3. Services
  4. Pipes

In a module file, declarations is an array of all the components, directives and custom pipes.

The imports array imports other modules into this module. We can import our custom module and also can use many useful modules that Angular provides, such as FormsModule, HttpClientModule.

The providers array defines all the services we want to provide. We can also add @Injectable({ providedIn: 'root' }) in our service.

The bootstrap array is used for starting the app. It defines which component is available right in that index.html file. And typically, you only have one component there, <app-root></app-root>.

The app routing module simply imports the router module Angular offers us and uses a special method, forRoot.

Then we export the RouterModule because every module works on its own in Angular. They don’t communicate with each other. If you declare a component in a certain module, then we can only use it in this module.

Feature Modules

Feature Modules group together components, directives, pipes, that used in a certain feature area of your application. For example, we can split our app into products Module, Orders Module, etc.

In our app, we have three main feature areas: Recipes, shopping list, and auth.

@NgModule({
  declarations: [
      RecipesComponent,
      RecipeListComponent,
      RecipeDetailComponent,
      RecipeItemComponent,
      RecipeStartComponent,
      RecipeEditComponent,
    ],
    imports: [
      RouterModule,
      CommonModule,
      ReactiveFormsModule
    ],
    exports: [
      RecipesComponent,
      RecipeListComponent,
      RecipeDetailComponent,
      RecipeItemComponent,
      RecipeStartComponent,
      RecipeEditComponent,
    ]
})
export class RecipesModule {

}

How can we use this RecipesModule in our app module? We first need to export all the components in the RecipesModule. Then, in the app module, we need to import this RecipesModule. But now, we do not have Route module in the recipes module, because everything in a module works standalone. We could simply import the RouterModule into our recipes module. Then we also need to import CommonModule and ReactiveFormsModule.

Whatever you declare in a module and whatever you use in the templates of these components has to be imported in that module. The only exception is services.

Adding Routes to Feature Modules

We can also move the recipes related route configuration away from the app routing module and into our recipes module.

To make this module clean, create a separate file called recipes-routing.module.ts.

const routes: Routes = [
  {
    path: 'recipes',
    component: RecipesComponent,
    canActivate: [AuthGuard],
    children: [
      { path: '', component: RecipeStartComponent },
      { path: 'new', component: RecipeEditComponent },
      { path: ':id',
        component: RecipeDetailComponent,
        resolve: [RecipesResolverService]
      },
      { path: ':id/edit',
        component: RecipeEditComponent,
        resolve: [RecipesResolverService]
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class RecipesRoutingModule {
}

After that, we import this RecipesRoutingModule in the recipes module.

imports: [
    RouterModule,
    CommonModule,
    ReactiveFormsModule,
    RecipesRoutingModule
  ],

forChild will automatically merge the child routing configuration with the root route.

Component Declarations in a Module

In a module, we do not just add to declarations what we are using a template, but also, we need to add any component in a route that we load via routing.

For example, in the recipes module, we use <app-recipe-list>.

<div class="row">
  <div class="col-md-5">
    <app-recipe-list></app-recipe-list>
  </div>
  <div class="col-md-7">
    <router-outlet></router-outlet>
  </div>
</div>
<br>
<br>

So we need to declare RecipeListComponent.

declarations: [
    RecipesComponent,
    RecipeListComponent,
    RecipeDetailComponent,
    RecipeItemComponent,
    RecipeStartComponent,
    RecipeEditComponent,
  ],

But when we load the routes via routing, we also need many other components.

const routes: Routes = [
  {
    path: 'recipes',
    component: RecipesComponent,
    canActivate: [AuthGuard],
    children: [
      { path: '', component: RecipeStartComponent },
      { path: 'new', component: RecipeEditComponent },
      { path: ':id',
        component: RecipeDetailComponent,
        resolve: [RecipesResolverService]
      },
      { path: ':id/edit',
        component: RecipeEditComponent,
        resolve: [RecipesResolverService]
      }
    ]
  }
];

Therefore, we should also declare these components in the module.

Now, we manage the loading of our components in the recipes routing file. Thus, we do not need to export those components any more.

@NgModule({
  declarations: [
    RecipesComponent,
    RecipeListComponent,
    RecipeDetailComponent,
    RecipeItemComponent,
    RecipeStartComponent,
    RecipeEditComponent,
  ],
  imports: [
    RouterModule,
    CommonModule,
    ReactiveFormsModule,
    RecipesRoutingModule
  ]
})
export class RecipesModule {

}

Because we are now only using them internally in the recipes module.

tags: Angular