JavaScript 第26章:Angular 基础

Angular是由Google维护的一个开源框架,用于构建Web应用程序。Angular提供了一套完整的解决方案来构建动态Web应用,它利用TypeScript语言来编写组件,并提供了一系列内置指令和管道来简化前端开发工作。

Angular 概述

Angular是一个完整的MVC(Model-View-Controller)框架,它旨在简化Web应用的开发流程,通过模块化的方式组织代码,提供依赖注入系统,以及丰富的指令和管道等功能。Angular支持组件化开发,这意味着你可以把应用分割成小的、可重用的组件。

组件与服务

在Angular中,组件是构成应用的基本单元。每个组件都由三个部分组成:一个类(组件类),一个HTML模板,以及一个样式表。组件类负责业务逻辑,模板定义了组件的视图,样式表则负责组件的外观。

服务则是封装了应用逻辑的部分,通常用来处理数据获取、认证等跨组件的工作。服务可以通过依赖注入(DI)机制在组件中使用。

模板语法

Angular模板语法允许你在HTML中嵌入TypeScript代码,以便实现动态内容。你可以使用*ngFor来遍历数据集合,使用*ngIf来控制元素的显示隐藏,以及其他内置指令来控制DOM元素的行为。

数据绑定

Angular支持多种类型的数据绑定:

  • 属性绑定:将组件类中的属性值绑定到HTML元素的属性上,如[attr.class]="className"
  • 事件绑定:将事件(如点击)与组件类中的方法绑定起来,如(click)="onClick($event)"
  • 双向数据绑定:通过[(ngModel)]指令来同步HTML控件和组件类中的属性。

实战案例:Angular入门应用

下面是一个简单的Angular入门应用,该应用将展示一个待办事项列表,并允许用户添加和删除待办事项。

创建Angular应用

首先,你需要安装Angular CLI来创建一个新的Angular项目:

npm install -g @angular/cli
ng new my-todo-app
cd my-todo-app
修改AppComponent

接下来,修改src/app/app.component.ts文件,创建一个简单的待办事项列表。

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-todo-app';
  todos: string[] = [];

  addTodo(todo: string) {
    this.todos.push(todo);
  }

  removeTodo(index: number) {
    this.todos.splice(index, 1);
  }
}
修改AppComponent模板

接着,在src/app/app.component.html中添加模板代码:

<h1>{{ title }}</h1>
<input [(ngModel)]="newTodo" placeholder="输入待办事项">
<button (click)="addTodo(newTodo)">添加</button>
<ul>
  <li *ngFor="let todo of todos; let i = index">
    {{ todo }}
    <button (click)="removeTodo(i)">删除</button>
  </li>
</ul>

注意,这里使用了ngModel来进行双向数据绑定,你需要导入FormsModule来启用模板驱动的表单。

导入FormsModule

src/app/app.module.ts中导入FormsModule

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // 导入FormsModule

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule // 添加FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
启动应用

最后,运行以下命令启动应用:

ng serve

打开浏览器访问 http://localhost:4200,你应该可以看到一个简单的待办事项列表应用。

这个例子展示了如何使用Angular创建一个简单的Web应用,包括如何定义组件、使用模板语法进行数据绑定以及处理用户输入。通过这些基础知识,你可以开始构建更复杂的应用程序了。

接下来,让我们继续深入探讨Angular的基础知识,并通过扩展之前的待办事项应用来进一步演示Angular的一些核心特性。

更深入地了解Angular特性

依赖注入(Dependency Injection, DI)

Angular的依赖注入系统允许你轻松地管理和传递依赖项。依赖注入可以让你在组件内部声明它所需要的服务或其他对象,而不必关心这些对象是如何被创建的。Angular会负责创建这些依赖并将它们注入到需要的地方。

指令(Directives)

除了Angular内置的指令(如*ngFor, *ngIf等),你还可以创建自定义指令来扩展HTML的行为。自定义指令可以用来改变DOM元素的行为、样式,甚至可以响应用户交互。

管道(Pipes)

管道是在Angular模板中使用的特殊函数,用于转换一个值。例如,可以使用内置的日期管道{{ date | date:'short' }}来格式化日期字符串。

扩展待办事项应用

现在,让我们通过添加一些新的功能来扩展之前的待办事项应用,比如使用服务来管理待办事项列表、使用自定义指令来高亮显示完成的任务、以及使用管道来格式化日期。

创建服务来管理待办事项

首先,我们需要创建一个服务来管理待办事项列表。使用Angular CLI来创建一个服务:

ng generate service todo

然后编辑src/app/todo.service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class TodoService {
  private todos: { text: string, completed: boolean, createdAt: Date }[] = [];

  constructor() { }

  addTodo(text: string): void {
    this.todos.push({ text, completed: false, createdAt: new Date() });
  }

  removeTodo(index: number): void {
    this.todos.splice(index, 1);
  }

  getTodos(): { text: string, completed: boolean, createdAt: Date }[] {
    return this.todos;
  }

  toggleTodo(index: number): void {
    this.todos[index].completed = !this.todos[index].completed;
  }
}
在组件中使用服务

接下来,我们需要在AppComponent中使用TodoService来管理待办事项列表:

import { Component } from '@angular/core';
import { TodoService } from './todo.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-todo-app';
  newTodo = '';

  constructor(private todoService: TodoService) { }

  addTodo() {
    this.todoService.addTodo(this.newTodo);
    this.newTodo = '';
  }

  removeTodo(index: number) {
    this.todoService.removeTodo(index);
  }

  toggleTodo(index: number) {
    this.todoService.toggleTodo(index);
  }

  getTodos() {
    return this.todoService.getTodos();
  }
}
创建自定义指令

我们可以创建一个自定义指令来高亮显示已完成的任务:

import { Directive, HostBinding, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  @Input() appHighlight: boolean;

  @HostBinding('class.completed') get highlight() {
    return this.appHighlight;
  }
}

注册自定义指令:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HighlightDirective } from './highlight.directive';
import { TodoService } from './todo.service';

@NgModule({
  declarations: [
    AppComponent,
    HighlightDirective
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [TodoService],
  bootstrap: [AppComponent]
})
export class AppModule { }
更新模板

更新app.component.html来使用自定义指令和管道:

<h1>{{ title }}</h1>
<input [(ngModel)]="newTodo" placeholder="输入待办事项">
<button (click)="addTodo()">添加</button>
<ul>
  <li *ngFor="let todo of getTodos(); let i = index" appHighlight="todo.completed">
    <input type="checkbox" [(ngModel)]="todo.completed">
    <span [ngClass]="{ completed: todo.completed }">{{ todo.text }}</span>
    <small>{{ todo.createdAt | date }}</small>
    <button (click)="removeTodo(i)">删除</button>
  </li>
</ul>

总结

通过这些扩展,我们不仅增强了待办事项应用的功能,还引入了Angular的服务、自定义指令以及管道等特性。这些特性使得Angular成为构建复杂Web应用程序的理想选择。希望这些示例能够帮助你更好地理解Angular,并鼓励你在自己的项目中运用这些知识。

我们将继续扩展待办事项应用,并探讨Angular的一些其他重要特性,如路由管理、表单处理、以及如何使用Angular Material来美化应用界面。

Angular路由管理

为了使待办事项应用更加实用,我们可以添加一些额外的页面,如登录页面、用户信息页面等,并使用Angular路由来管理这些页面之间的导航。

创建路由

首先,我们需要创建一个新的组件作为登录页面,并配置路由。

  1. 使用Angular CLI创建一个新的组件:

    ng generate component login
    
  2. 编辑login.component.html,创建一个简单的登录表单:

    <h1>登录</h1>
    <form (ngSubmit)="onLogin()">
      <div>
        <label for="username">用户名:</label>
        <input id="username" type="text" [(ngModel)]="username" name="username" required>
      </div>
      <div>
        <label for="password">密码:</label>
        <input id="password" type="password" [(ngModel)]="password" name="password" required>
      </div>
      <button type="submit">登录</button>
    </form>
    
  3. 编辑login.component.ts

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.css']
    })
    export class LoginComponent {
      username = '';
      password = '';
    
      onLogin() {
        // 登录逻辑
      }
    }
    
  4. 配置路由:

    编辑app-routing.module.ts

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { AppComponent } from './app.component';
    import { LoginComponent } from './login/login.component';
    
    const routes: Routes = [
      { path: '', component: AppComponent },
      { path: 'login', component: LoginComponent }
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }
    
  5. 更新app.component.html以包含路由出口:

    <router-outlet></router-outlet>
    

表单处理

在上面的登录页面中,我们使用了模板驱动的表单。Angular还支持反应式的表单处理,这对于更复杂的表单场景非常有用。下面是一个使用反应式表单的例子:

使用反应式表单
  1. 更新login.component.ts以使用反应式表单:

    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    
    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.css']
    })
    export class LoginComponent implements OnInit {
      loginForm: FormGroup;
    
      constructor(private fb: FormBuilder) { }
    
      ngOnInit() {
        this.loginForm = this.fb.group({
          username: ['', Validators.required],
          password: ['', Validators.required]
        });
      }
    
      onLogin() {
        if (this.loginForm.valid) {
          // 登录逻辑
        }
      }
    }
    
  2. 更新login.component.html以使用formControlName

    <form [formGroup]="loginForm" (ngSubmit)="onLogin()">
      <div>
        <label for="username">用户名:</label>
        <input id="username" type="text" formControlName="username" required>
      </div>
      <div>
        <label for="password">密码:</label>
        <input id="password" type="password" formControlName="password" required>
      </div>
      <button type="submit">登录</button>
    </form>
    

使用Angular Material

Angular Material 提供了许多预构建的组件,可以快速美化你的应用界面。下面我们来添加一些Material组件来改善待办事项应用的外观。

  1. 安装Angular Material:

    ng add @angular/material
    
  2. 选择一个合适的主题颜色方案,并在全局样式文件中导入:

    /* styles.css */
    @import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
    
  3. app.module.ts中导入所需的Material模块:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { AppComponent } from './app.component';
    import { HighlightDirective } from './highlight.directive';
    import { TodoService } from './todo.service';
    import { RouterModule } from '@angular/router';
    import { AppRoutingModule } from './app-routing.module';
    import { LoginComponent } from './login/login.component';
    import { MatInputModule } from '@angular/material/input';
    import { MatButtonModule } from '@angular/material/button';
    import { MatCheckboxModule } from '@angular/material/checkbox';
    import { MatListModule } from '@angular/material/list';
    
    @NgModule({
      declarations: [
        AppComponent,
        HighlightDirective,
        LoginComponent
      ],
      imports: [
        BrowserModule,
        FormsModule,
        RouterModule,
        AppRoutingModule,
        MatInputModule,
        MatButtonModule,
        MatCheckboxModule,
        MatListModule
      ],
      providers: [TodoService],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  4. 更新app.component.html以使用Material组件:

    <mat-toolbar color="primary">
      <span>{{ title }}</span>
    </mat-toolbar>
    <mat-list>
      <mat-list-item *ngFor="let todo of getTodos(); let i = index">
        <mat-checkbox [(ngModel)]="todo.completed"></mat-checkbox>
        <mat-list-item-content>
          <span [ngClass]="{ completed: todo.completed }">{{ todo.text }}</span>
          <small>{{ todo.createdAt | date }}</small>
        </mat-list-item-content>
        <button mat-button (click)="removeTodo(i)">删除</button>
      </mat-list-item>
    </mat-list>
    
  5. 更新login.component.html以使用Material组件:

    <mat-toolbar color="primary">
      <span>登录</span>
    </mat-toolbar>
    <form [formGroup]="loginForm" (ngSubmit)="onLogin()">
      <mat-form-field appearance="fill">
        <mat-label>用户名</mat-label>
        <input matInput formControlName="username" required>
      </mat-form-field>
      <mat-form-field appearance="fill">
        <mat-label>密码</mat-label>
        <input matInput type="password" formControlName="password" required>
      </mat-form-field>
      <button mat-raised-button color="primary" type="submit">登录</button>
    </form>
    

总结

通过上述步骤,我们不仅增强了待办事项应用的功能,还引入了Angular的路由管理、表单处理以及Angular Material来提升应用的用户体验。这些特性使得Angular成为一个强大的框架,适用于构建高度交互性的Web应用程序。

好的,我们继续扩展待办事项应用,并进一步探讨Angular的一些其他特性,如状态管理、单元测试等。此外,我们还将讨论如何优化和重构代码,以确保应用的可维护性和可扩展性。

状态管理:使用NgRx

对于较大的应用来说,状态管理变得非常重要,特别是当多个组件需要共享状态时。Angular生态系统中,NgRx是一个流行的库,用于实现Redux模式的状态管理。下面我们将使用NgRx来管理待办事项的状态。

安装NgRx

首先,安装NgRx相关的包:

ng add @ngrx/store
ng add @ngrx/entity
创建State和Reducer

创建一个状态来存储待办事项列表,并定义一个reducer来处理状态更新。

  1. 创建一个store模块:

    ng generate module store --flat --module=app
    
  2. store模块中创建状态和reducer:

    // store/todo.state.ts
    export interface Todo {
      id: number;
      text: string;
      completed: boolean;
      createdAt: Date;
    }
    
    export interface State {
      todos: Todo[];
    }
    
    export const initialState: State = {
      todos: []
    };
    
    // store/todo.reducer.ts
    import { createReducer, on } from '@ngrx/store';
    import { addTodo, removeTodo, toggleTodo } from './todo.actions';
    
    export const todoReducer = createReducer(
      initialState,
      on(addTodo, (state, { todo }) => ({
        ...state,
        todos: [...state.todos, todo]
      })),
      on(removeTodo, (state, { id }) => ({
        ...state,
        todos: state.todos.filter(todo => todo.id !== id)
      })),
      on(toggleTodo, (state, { id }) => ({
        ...state,
        todos: state.todos.map(todo =>
          todo.id === id ? { ...todo, completed: !todo.completed } : todo
        )
      }))
    );
    
  3. 创建Action文件:

    // store/todo.actions.ts
    import { createAction, props } from '@ngrx/store';
    
    export const addTodo = createAction(
      '[Todo] Add Todo',
      props<{ todo: Todo }>()
    );
    
    export const removeTodo = createAction(
      '[Todo] Remove Todo',
      props<{ id: number }>()
    );
    
    export const toggleTodo = createAction(
      '[Todo] Toggle Todo',
      props<{ id: number }>()
    );
    
  4. store.module.ts中注册reducers:

    // store.module.ts
    import { NgModule } from '@angular/core';
    import { StoreModule } from '@ngrx/store';
    import { todoReducer } from './todo.reducer';
    
    @NgModule({
      imports: [
        StoreModule.forRoot({ todos: todoReducer })
      ]
    })
    export class StoreModule { }
    
在组件中使用NgRx

接下来,我们需要在组件中使用NgRx来获取和更新状态。

  1. app.component.ts中使用select来获取状态:

    import { Component, OnInit } from '@angular/core';
    import { Store } from '@ngrx/store';
    import { addTodo, removeTodo, toggleTodo } from './store/todo.actions';
    import { selectTodos } from './store/todo.selectors';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      todos$ = this.store.select(selectTodos);
      newTodo = '';
    
      constructor(private store: Store) { }
    
      ngOnInit() {
        // 初始化逻辑
      }
    
      addTodo() {
        if (this.newTodo.trim()) {
          const newTodo = {
            id: Date.now(),
            text: this.newTodo,
            completed: false,
            createdAt: new Date()
          };
          this.store.dispatch(addTodo({ todo: newTodo }));
          this.newTodo = '';
        }
      }
    
      removeTodo(id: number) {
        this.store.dispatch(removeTodo({ id }));
      }
    
      toggleTodo(id: number) {
        this.store.dispatch(toggleTodo({ id }));
      }
    }
    
  2. 创建选择器来获取状态:

    // store/todo.selectors.ts
    import { createFeatureSelector, createSelector } from '@ngrx/store';
    import { State } from './todo.state';
    
    const selectTodoFeature = createFeatureSelector<State>('todos');
    
    export const selectTodos = createSelector(
      selectTodoFeature,
      state => state.todos
    );
    
更新模板

最后,更新app.component.html以反映状态变化:

<h1>{{ title }}</h1>
<input [(ngModel)]="newTodo" placeholder="输入待办事项">
<button (click)="addTodo()">添加</button>
<ul>
  <li *ngFor="let todo of todos$ | async; let i = index">
    <mat-checkbox [(ngModel)]="todo.completed" (change)="toggleTodo(todo.id)"></mat-checkbox>
    <span [ngClass]="{ completed: todo.completed }">{{ todo.text }}</span>
    <small>{{ todo.createdAt | date }}</small>
    <button mat-button (click)="removeTodo(todo.id)">删除</button>
  </li>
</ul>

单元测试

Angular提供了Angular CLI工具来帮助编写单元测试。我们可以为组件和服务编写单元测试,以确保它们按预期工作。

创建单元测试
  1. AppComponent编写单元测试:

    ng generate component app --spec=false
    
  2. 编写测试代码:

    // app.component.spec.ts
    import { ComponentFixture, TestBed } from '@angular/core/testing';
    import { AppComponent } from './app.component';
    import { StoreModule, combineReducers } from '@ngrx/store';
    import { provideMockStore } from '@ngrx/store/testing';
    import { todoReducer } from './store/todo.reducer';
    import { addTodo } from './store/todo.actions';
    
    describe('AppComponent', () => {
      let component: AppComponent;
      let fixture: ComponentFixture<AppComponent>;
    
      beforeEach(async () => {
        await TestBed.configureTestingModule({
          declarations: [AppComponent],
          imports: [
            StoreModule.forRoot({ todos: todoReducer }),
          ],
          providers: [provideMockStore()]
        }).compileComponents();
      });
    
      beforeEach(() => {
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should create the app', () => {
        expect(component).toBeTruthy();
      });
    
      it('should dispatch addTodo action when addTodo is called', () => {
        const storeSpy = jasmine.createSpyObj('Store', ['dispatch']);
        component['store'] = storeSpy;
    
        component.addTodo();
    
        expect(storeSpy.dispatch).toHaveBeenCalledWith(addTodo({ todo: { id: expect.any(Number), text: '', completed: false, createdAt: expect.any(Date) } }));
      });
    });
    

总结

通过这些步骤,我们不仅增强了待办事项应用的功能,还引入了状态管理(NgRx)、单元测试等高级特性。这些特性使得Angular成为一个强大且灵活的框架,适合构建复杂的企业级Web应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896518.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

明源云ERP报表服务GetErpConfig.aspx接口存在敏感信息泄露

一、漏洞简介 在访问 /service/Mysoft.Report.Web.Service.Base/GetErpConfig.aspx?erpKeyerp60 路径时&#xff0c;返回了包含敏感信息的响应。这些信息包括但不限于数据库连接字符串、用户名、密码、加密密钥等。这些敏感信息的暴露可能导致以下风险&#xff1a;数据库访问…

Linux 常用命令(一)

目录 ll命令&#xff1a;显示指定文件的详细属性信息 ls&#xff1a;显示目录中文件及其属性信息 mkdir命令&#xff1a;创建目录文件 touch&#xff1a;创建空文件与修改时间戳 rm命令&#xff1a;删除文件或目录 cd命令&#xff1a;切换目录 chmod命令&#xff1a;改变…

llama.cpp 去掉打印,只显示推理结果

llama.cpp 去掉打印&#xff0c;只显示推理结果 1 llama.cpp/common/log.h #define LOG_INF(...) LOG_TMPL(GGML_LOG_LEVEL_INFO, 0, __VA_ARGS__) #define LOG_WRN(...) LOG_TMPL(GGML_LOG_LEVEL_WARN, 0, __VA_ARGS__) #define LOG_ERR(…

docker部署es与kibana Mac

1. 创建网络 神一样的链接&#xff0c;不用谢&#xff1a; 1.Docker命令链接&#xff1a;黑马整理的docker速成链接 2.jdk11链接&#xff1a;jdk11 3.神资源链接&#xff1a;别点&#xff0c;要脸 注意&#xff1a;es需要先安装jdk环境&#xff0c;推荐jdk11&#xff0c;否则…

MySQL企业常见架构与调优经验分享

文章目录 一、选择 PerconaServer、MariaDB 还是 MYSQL二、常用的 MYSQL 调优策略三、MYSOL 常见的应用架构分享四、MYSOL 经典应用架构 观看学习课程的笔记&#xff0c;分享于此~ 课程&#xff1a;MySQL企业常见架构与调优经验分享 mysql官方优化文档 一、选择 PerconaServer、…

基于SSM的的水电管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Keil8051 下载与安装

文章目录 下载方法&#xff08;一&#xff09;官网下载&#xff08;二&#xff09;百度网盘下载 安装步骤小技巧 下载方法 &#xff08;一&#xff09;官网下载 1&#xff0c;进入官网&#xff1a;https://www.keil.com/。 2&#xff0c;单击“download”按钮&#xff0c;进…

如何快速解决游戏提示系统中的emp.dll缺失问题

emp.dll是一个动态链接库&#xff08;Dynamic Link Library, DLL&#xff09;文件&#xff0c;这类文件在Windows操作系统中扮演着至关重要的角色。它们包含了可由多个程序同时使用的代码和数据&#xff0c;其主要目的是实现模块化&#xff0c;以便于程序的更新和动态链接。emp…

在VMware上创建虚拟机以及安装Linux操作系统,使用ssh进行远程连接VMware安装注意点 (包含 v1,v8两张网卡如果没有的解决办法)

一&#xff0c;VMware上创建虚拟机 1.VMware下载 1&#xff09;点击VMware官网进入官网 网址:VMware by Broadcom - Cloud Computing for the EnterpriseOptimize cloud infrastructure with VMware for app platforms, private cloud, edge, networking, and security.https…

语言/图像/视频模型一网打尽!BigModel大模型开放平台助力开发者轻松打造AI新应用!

2024年8⽉28⽇&#xff0c;在ACM SIGKDD&#xff08;国际数据挖掘与知识发现⼤会&#xff0c;KDD&#xff09;上会议现场&#xff0c;智谱AI重磅推出了新⼀代全⾃研基座⼤模型 GLM-4-Plus、图像/视频理解模型 GLM-4V-Plus 和⽂⽣图模型 CogView3-Plus。这些新模型&#xff0c;已…

数据驱动,漫途能耗管理系统打造高效节能新生态!

在我国能源消耗结构中&#xff0c;工业企业所占能耗比例相对较大。为实现碳达峰、碳中和目标&#xff0c;工厂需强化能效管理&#xff0c;减少能耗与成本。高效的能耗管理系统通过数据采集与分析&#xff0c;能实时监控工厂能源使用及报警情况&#xff0c;为节能提供数据。构建…

梦熊十三连测题解

加减乘除 1.通过造样例可知&#xff1a;注意到两类操作并不会改变单调性&#xff0c;即对于任意 x≤y&#xff0c;在操作后仍然满足 x≤y。 2.所以我们就可以将原序列升序排序&#xff0c;分别通过二分找出最大和最小的下标。 3.时间复杂度&#xff1a;O(n*)。 代码如下&am…

android11 usb摄像头添加多分辨率支持

部分借鉴于&#xff1a;https://blog.csdn.net/weixin_45639314/article/details/142210634 目录 一、需求介绍 二、UVC介绍 三、解析 四、补丁修改 1、预览的限制主要存在于hal层和framework层 2、添加所需要的分辨率&#xff1a; 3、hal层修改 4、frameworks 5、备…

漏洞挖掘JS构造新手向

前置思路文章 JS逆向混淆前端对抗 油猴JS逆向插件 JS加解密之mitmproxy工具联动Burp JS挖掘基础 伪协议 JavaScript伪协议是一种在浏览器中模拟网络请求的方法。它使用window.XMLHttpRequest对象或fetch()方法来模拟发送HTTP请求&#xff0c;而不是通过实际的网络请求来获…

【H2O2|全栈】JS入门知识(五)

目录 JS 前言 准备工作 数组API&#xff08;一&#xff09; API概念 数组常见API&#xff08;一&#xff09; arguments 作用域 概念 全局作用域 局部作用域 块级作用域 变量的作用域 作用域链 案例 预解析 概念 变量预解析 函数预解析 案例 对象 概念 …

MySQL 异常: “Host ‘xxx‘ is not allowed to connect to this MySQL server“

update user set host % where user root; FLUSH PRIVILEGES; 这两行代码就行

Mysql 和MongoDB用户访问权限问题

Mysql 刚给二线运维排查了一个问题&#xff0c;Mysql安装完可用&#xff0c;且可用navicat连接&#xff0c;项目中通过127.0.0.1去连数据库报错了。错误是access denied for user ‘root’localhost,排查思路 1. 密码是否正确 &#xff08;不需要重置。到Mysql的安装目录下找…

开发规范 - mac系统1小时装机极速装机开发环境

idea 官网下载&#xff0c;然后想办法破解 idea必备配置 设置自动import IDEA插件安装 idea必备插件 maven helperlombokMybatisX jdk配置 jdk不用单配配置&#xff0c;在idea中&#xff0c;选择一个语言环境&#xff08;jdk8/jdk11/jdk17…&#xff09;,然后默认下载j…

picgo的gitee图床配置

首先picgo默认没有gitee&#xff0c;需要装插件 然后gitee

每月洞察:App Store 和 Google Play 的主要更新

Google Play 和 App Store 的算法不断发展&#xff0c;定期更新和变化会显着影响其功能。对于开发人员和营销人员来说&#xff0c;跟上这些变化至关重要&#xff0c;因为它们会直接影响应用发现和排名。 本文将深入探讨 Google Play 和 App Store 的最新更新&#xff0c;解释它…