2019独角兽企业重金招聘Python工程师标准>>> hot3.png

本文使用 Angular 2 搭建一个 TODO MVC 的例子。如果你不知道什么是 TODO MVC 的话,引用官方的一句话是:“ToDoMVC Helping you select an MV* framework”。如果你没听说过什么是 TODO MVC,下图是本文完成后的大概样子。

todo-demo

本文需要做到:

  • 使用 Angular Cli 初始化一个 TODO MVC 项目。
  • 创建一个 Todo 类。用来描述 todo 的信息。
  • 创建一个 TodoService,用来对 todo 信息的增删改查。
  • 使用 AppComponent 来向用户展示。

1. 使用 Angular CLI 来初始化你的 Todo Application

使用 Angular CLI 是一个最简单高效的方法来创建你的 Angular 项目。如果你对 Angular 还不熟悉的话,可以看看我之前写的一篇文章,对 Angular 的历史,核心及项目结构有一个了解。

  • 安装 Angular CLI

    新版的angular-cli已改名成@angular/cli,更符合angular官方的命名规则

    >npm install -g @angular/cli

    等待安装完成后,若没有报错信息,在cmd中输入一下命令进行验证

    >ng -v

        _                      _                 ____ _     ___/ \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|/ △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |/ ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
    /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___||___/@angular/cli: 1.1.0node: 6.10.3os: win32 x64
    

    出现以上结果,证明 angular cli 安装成功

  • 初始化你的项目

    使用 angular-cli 创建第一个工程。ng new 工程名

    >ng new todo-app

    请耐心等待。 创建新项目需要花费很多时间,安装npm包需要比较长的时间。

  • 启动服务

    >cd todo-app

    >ng serve

    正常情况下,启动成功后浏览器会自动打开。或者你可以使用 http://localhost:4200/. 来访问。

2. 创建 Todo Class

  • 使用 Angular CLI 创建 Todo 对象

    ng g cl Todo

    该命令会创建一个 TypeScript 类:

    src/app/todo.ts

    文件 todo.ts 内容很简单,如下(当然你也可以手动创建):

    export class Todo {
    }
    
  • 修改 todo 对象

    export class Todo {id: number;title: string = '';complete: boolean = false;constructor(values: Object = {}) {Object.assign(this, values);}
    }
    

    在这个类里面我们定义了三个属性和一个构造函数:

    • id: number类型, todo 的 id

    • title: string类型, todo 的标题

    • complete: boolean类型, 用来表示 todo 是否已经完成

    • constructor:构造函数,方便我们 new 一个 todo 对象:

2. 创建 TodoService

TodoService 用来管理 Todo 实例的增删改查功能。这里我们会把数据直接保存在内存里。在实际的生产中一般会访问远程接口的 API 等,但这不是本文的重点。

  • 创建 TodoService 对象

    ng g s Todo

    该命令会创建一个两个文件:

    src\app\todo.service.spec.ts

    src\app\todo.service.ts

    todo.service.ts :

    import { Injectable } from '@angular/core';@Injectable()
    export class TodoService {constructor() { }}
    

    todo.service.spec.ts (测试):

    import { TestBed, inject } from '@angular/core/testing';
    import { TodoService } from './todo.service';describe('TodoService', () => {
    beforeEach(() => {TestBed.configureTestingModule({providers: [TodoService]});
    });it('should be created', inject([TodoService], (service: TodoService) => {expect(service).toBeTruthy();
    }));
    });
    
  • 修改 todo.service.ts 增加逻辑代码

    import { Todo } from './todo';
    import { Injectable } from '@angular/core';@Injectable()
    export class TodoService {// 增加 todo 时模拟自增idid: number = 0;// 用于在内存里保存 todo 信息todos: Todo[] = [];constructor() { }add(todo: Todo): Todo {if (!todo.id) {todo.id = ++this.id;}this.todos.push(todo);return todo;}deleteById(id: number): void {this.todos = this.todos.filter(todo => todo.id !== id);}update(todo: Todo): Todo {let t = this.findById(todo.id);if (!t) {return null;}Object.assign(t, todo);return t;}findById(id: number): Todo {return this.todos.filter(todo => todo.id === id).pop();}findAll(): Todo[] {return this.todos;}toggleTodoComplete(todo: Todo){todo.complete = !todo.complete;let u = this.update(todo);return u;}
    }
    
  • 修改 todo.service.spec.ts 增加测试代码

    编写完 todo.service.ts 逻辑代码后,你需要确认你的服务接口是不是正常。这时候需要在todo.service.spec.ts编写 TodoService 的测试代码

    import { TestBed, inject } from '@angular/core/testing';import { TodoService } from './todo.service';
    import { Todo } from './todo';describe('TodoService', () => {
    beforeEach(() => {TestBed.configureTestingModule({providers: [TodoService]});
    });it('should be created', inject([TodoService], (service: TodoService) => {expect(service).toBeTruthy();
    }));it('get all todos', inject([TodoService], (service: TodoService) => {expect(service.findAll()).toEqual([]);
    }));it('add todo ', inject([TodoService], (service: TodoService) => {let todo1 = new Todo({ title: 'test', complete: false });service.add(todo1);expect(service.findById(1)).toEqual(todo1);
    }));it('toggle todo complete', inject([TodoService], (service: TodoService) => {let todo = new Todo({title: 'test', complete: false});service.add(todo);let updatedTodo = service.toggleTodoComplete(todo);expect(updatedTodo.complete).toEqual(true);service.toggleTodoComplete(todo);expect(updatedTodo.complete).toEqual(false);}));});
    

    这里只写了部分测试代码,使用一下命令测试:

    ng test

    运行后浏览器会自动打开

    todo-test

  • 看看 todo.service.spec.ts 的结构

    ng test 使用 jasmine 来进行测试,关于更多的内容你可以查看 jasmine 官方文档

    jasmine

    测试代码会调用全局的 jasmine 函数 describe 。describe 函数包含两个参数,一个描述,另外一个便是测试方法。

      beforeEach(() => {TestBed.configureTestingModule({providers: [TodoService]});
    });
    

    TestBed 是 @angular/core/testing 提供的用来配置和创建 Angular Test 模块。我们使用 TestBed.configureTestingModule()方法配置相关信息。 providers 属性告诉测试模块,当我们运行测试用例时需要什么东西。

    it('get all todos', inject([TodoService], (service: TodoService) => {expect(service.findAll()).toEqual([]);
    }));
    

    it 类似于 java 里的测试单元,该方法的第一个参数是一个名称,第二个参数是真正的测试方法。TestBad 注册器会为我们注入TodoService,以便我们在我们的测试方法里面访问到这个service。

3. 编写 AppComponent 组件

当我们初始化完这个项目的时候,Angular CLI 已经自动为我们创建了一个主组件 AppComponent ,包含了一下4个文件:

src/app/app.component.css       // css 样式文件
src/app/app.component.html      // html 结构文件
src/app/app.component.spec.ts   // 测试文件
src/app/app.component.ts        //逻辑代码

到这里整个

  • 修改 app.component.html

    1. 我们先看一下app.component.html原来的样子:
  • 编写 app.component.ts

    1. 我们在先看一下 Angular CLI 默认为我们创建的这个文件里都有什么:

      <h1>
      {{title}}
      </h1>
      
    2. 我们需要修改成我们的需要的结构:

       <section class="todoapp">
      <header class="header"><h1>Todos</h1><input class="new-todo" placeholder="What needs to be done?" autofocus="" [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()">
      </header>
      <section class="main" *ngIf="todos.length > 0"><ul class="todo-list"><li *ngFor="let todo of todos" [class.completed]="todo.complete"><div class="view"><input class="toggle" type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete"><label>{{todo.title}}</label><button class="destroy" (click)="removeTodo(todo)"></button></div></li></ul>
      </section>
      <footer class="footer" *ngIf="todos.length > 0"><span class="todo-count"><strong>{{todos.length}}</strong> {{todos.length == 1 ? 'item' : 'items'}} left</span>
      </footer>
      </section>
      
    3. 如果你对上面的模版语法还不熟悉,没关系,这里对 Angular 2 的模版语法做一个简单的介绍:

      • [property]="expression": 属性绑定,会将表达式的值设置给 property 属性。
      • [style.color]="expression": 属性绑定,会将表达式的值设置给样式属性 color。
      • [class.special]="expression": 属性绑定,如果表达式为真,则为 class 属性添加 special 样式。
      • (event)="statement": 事件绑定,当发生 event 事件时执行 statement。
      • [(property)]="expression": 双向数据绑定,表达式的值变化会影响 property。property 的值变化也会影响表达式的值
  • app.component.html 各个部分解析

    1. 首先在最上面是一个 input ,用来创建新的todo对象:

      <input [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()" 其他属性 >
      
      • [(ngModel)]="newTodo.title" :

        双向数据绑定,在这里会绑定 newTodo.title 和这个 input 的 value 值。

      • (keyup.enter)="addTodo()" :

        事件绑定,当回车键发送 keyup 事件时,执行 addTodo() 这个方法。

    这里我们还没有在 AppComponent 里定义 newTodo 和 addTodo。 很快我们就会讲到,这里先试着了解 Angular 模版的语法。

    1. 接下来是一个 section 里面用于定义 todo 列表的展示方式:

      <section class="main" *ngIf="todos.length > 0">
      
      • *ngIf="todos.length > 0" :

        angular 内置指令,当 todos.length > 0 时才显示 section 和 section 的子元素。

    2. 接下来是 ul 里套着一个li:

      <li *ngFor="let todo of todos" [class.completed]="todo.complete">
      
      • *ngFor="let todo of todos" :

        angular 内置指令,循环 todos 对象,生成 n 条 li 标签,n = todos.length。并为每条 li 赋值一个 todo 对象。

      • [class.completed]="todo.complete" :

        当 todo.complete 等于 true 时,为该标签的 class 添加 completed 。

    3. 最后是是一个 view 用于展示每个 todo 的详细信息

      <div class="view"><input  type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete"><label>{{todo.title}}</label><button (click)="removeTodo(todo)"></button>
      </div>
      
      • (click)="toggleTodoComplete(todo)" :

        当发生点击事件时,会执行 toggleTodoComplete 方法 todo 对象作为参数传入。

      • [checked]="todo.complete" :

        绑定 todo.complete 的值到 checked 属性。

      • (click)="removeTodo(todo)" :

        当点击 button 按钮时,执行 removeTodo 方法,并将 todo 对象作为参数传入。

到这里整个 app.component.html 的所有部门都介绍完毕。当然你可能会一头雾水,里面的 todos ,newTodo 还是 addTodo() 等,都是些什么东西。他们要定义在哪里? 又是如何访问的。别着急,下面我们马上就会讲到。

  • 编写 app.component.ts

    1. 我们在先看一下 Angular CLI 默认为我们创建的这个文件里都有什么:

      import { Component } from '@angular/core';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
      })
      export class AppComponent {title = 'app works!';
      }
      

      这个文件很简单。首先是一个 @Component 的装饰器,装饰器作用在类上用来告诉 Angular 这个类的一些附加属性。而这些附加的属性就是称之为元数据

      • selector: 'app-root':

        css3 选择器,当 Angular 在模版里发现了 <app-root> 这个标签后,便会用本组件去渲染。

      • templateUrl: './app.component.html :

        模版Url,这里就是我们上面一小节讲到的 app.component.html。用于告诉 Angular 本组件该如何渲染。

      • styleUrls: ['./app.component.css'] :

        css Url,样式文件的路径。一个完美的 css 能让我们的组件看起来更赏心悦目。

    2. 接下来,我们要为 app.component.ts 注入 TodoService 服务。

      import {TodoService} from './todo.service';@Component({// ...providers: [TodoService]
      })
      export class AppComponent {// ...constructor(private todoService: TodoService) {}
      }
      
      • providers: [TodoService]

        我们在元数据里添加了一个 providers 属性。Angular 会根据 providers 的值会到注入器中查找是否已经有 TodoService 实例,如果没有,会自动帮我们实例化一个 TodoService 对象。并存放在注入器中。

      • constructor(private todoService: TodoService) {} :

        这句话便是真正的注入, Angular 注入器会为这个组件注入 TodoService 的实例,并赋值给 todoService 属性。其实这里等价于:

        // ...
        export class AppComponent {private todoService:TodoService;// ...constructor(todoService: TodoService) {this.todoService = todoService;}
        }
        
    3. 增加我们的逻辑代码:

      import { Component } from '@angular/core';
      import { TodoService } from './todo.service';
      import { Todo } from './todo';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'],providers: [TodoService]
      })
      export class AppComponent {newTodo: Todo = new Todo();constructor(private todoService:TodoService){}addTodo() {this.todoService.add(this.newTodo);this.newTodo = new Todo();}toggleTodoComplete(todo) {this.todoService.toggleTodoComplete(todo);}removeTodo(todo) {this.todoService.deleteById(todo.id);}get todos() {return this.todoService.findAll();}
      }
      

      你可能不信,增加完上面的代码,我们的应用已经能正常运行了,不过我们还是来看看这个文件的内容:

      • newTodo: Todo = new Todo(); :

        newTodo 属性用于新增 todo 对象时绑定属性。还记得我们页面的第一个 input 标签吗? <input [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()"> 这里对 input 值和 newTodo.title 的值做了双向绑定,只要这两个值中的一个变化,另外一个都会跟着变化。

      • addTodo() :

        addTodo() {this.todoService.add(this.newTodo);this.newTodo = new Todo();
        }
        

        可能你已经猜到了,当你在页面上按下回车时,那个(keyup.enter)="addTodo()" 调用方法的实现,就是在这里。addTodo会调用注入的 todoService 的 add 方法。把 newTodo 进行保存。并将 this.newTodo 赋值一个新的 Todo 对象。

      • toggleTodoComplete(todo) :

        toggleTodoComplete(todo) {this.todoService.toggleTodoComplete(todo);
        }
        

        页面<input type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete">,当你点击这个 checkbox 时,变会调用 toggleTodoComplete 方法并将 todo 对象传入,toggleTodoComplete 使用 todoService 服务的来转变 todo 的 complete 属性。当todo.complete 的值发生变化时,[checked] 的值也会跟着变化。

      • removeTodo(todo) :

        removeTodo(todo) {this.todoService.deleteById(todo.id);
        }
        

        页面<button (click)="removeTodo(todo)"></button>,当你点击删除按钮是,便会调用 removeTodo 方法,并传入 todo 对象作为方法的参数。而removeTodo 会根据传入的参数调用 todoService 服务的 deleteById 来删除这个 todo 对象。

      • get todos()

        get todos() {return this.todoService.findAll();
        }
        

        如果你对 java bean 的定义熟悉的话你应该能猜个大概。这个方法是一个属性方法。相当于定义了一个 todos 属性。 并为这个 todos 属性添加了 get 方法。所以当页面 <li *ngFor="let todo of todos" > 这个标签获取 todos 的数据时,便会调用 get todos() 方法。而 get todos() 会调用 todoService 服务的 findAll 方法,并返回所有的 todos。

    4. 编写我们的样式文件

      样式文件并不是本文的重点,这里贴出样式的代码,省的小伙伴自己编写。

      • ./src/style.css : 这个文件用于设置全局css属性:

        html,
        body {margin: 0;padding: 0;
        }button {margin: 0;padding: 0;border: 0;background: none;font-size: 100%;vertical-align: baseline;font-family: inherit;font-weight: inherit;color: inherit;-webkit-appearance: none;appearance: none;-webkit-font-smoothing: antialiased;-moz-font-smoothing: antialiased;font-smoothing: antialiased;
        }body {font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;line-height: 1.4em;background: #f5f5f5;color: #4d4d4d;min-width: 230px;max-width: 550px;margin: 0 auto;-webkit-font-smoothing: antialiased;-moz-font-smoothing: antialiased;font-smoothing: antialiased;font-weight: 300;
        }button,
        input[type="checkbox"] {outline: none;
        }.hidden {display: none;
        }
        
      • /src/app/app.component.css : 编写我们组件的样式

        .todoapp {background: #fff;margin: 130px 0 40px 0;position: relative;box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),0 25px 50px 0 rgba(0, 0, 0, 0.1);
        }.todoapp input::-webkit-input-placeholder {font-style: italic;font-weight: 300;color: #e6e6e6;
        }.todoapp input::-moz-placeholder {font-style: italic;font-weight: 300;color: #e6e6e6;
        }.todoapp input::input-placeholder {font-style: italic;font-weight: 300;color: #e6e6e6;
        }.todoapp h1 {position: absolute;top: -155px;width: 100%;font-size: 100px;font-weight: 100;text-align: center;color: rgba(175, 47, 47, 0.15);-webkit-text-rendering: optimizeLegibility;-moz-text-rendering: optimizeLegibility;text-rendering: optimizeLegibility;
        }.new-todo,
        .edit {position: relative;margin: 0;width: 100%;font-size: 24px;font-family: inherit;font-weight: inherit;line-height: 1.4em;border: 0;outline: none;color: inherit;padding: 6px;border: 1px solid #999;box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-font-smoothing: antialiased;font-smoothing: antialiased;
        }.new-todo {padding: 16px 16px 16px 60px;border: none;background: rgba(0, 0, 0, 0.003);box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
        }.main {position: relative;z-index: 2;border-top: 1px solid #e6e6e6;
        }label[for='toggle-all'] {display: none;
        }.toggle-all {position: absolute;top: -55px;left: -12px;width: 60px;height: 34px;text-align: center;border: none; /* Mobile Safari */
        }.toggle-all:before {content: '❯';font-size: 22px;color: #e6e6e6;padding: 10px 27px 10px 27px;
        }.toggle-all:checked:before {color: #737373;
        }.todo-list {margin: 0;padding: 0;list-style: none;
        }.todo-list li {position: relative;font-size: 24px;border-bottom: 1px solid #ededed;
        }.todo-list li:last-child {border-bottom: none;
        }.todo-list li.editing {border-bottom: none;padding: 0;
        }.todo-list li.editing .edit {display: block;width: 506px;padding: 13px 17px 12px 17px;margin: 0 0 0 43px;
        }.todo-list li.editing .view {display: none;
        }.todo-list li .toggle {text-align: center;width: 40px;/* auto, since non-WebKit browsers doesn't support input styling */height: auto;position: absolute;top: 0;bottom: 0;margin: auto 0;border: none; /* Mobile Safari */-webkit-appearance: none;appearance: none;
        }.todo-list li .toggle:after {content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
        }.todo-list li .toggle:checked:after {content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
        }.todo-list li label {white-space: pre-line;word-break: break-all;padding: 15px 60px 15px 15px;margin-left: 45px;display: block;line-height: 1.2;transition: color 0.4s;
        }.todo-list li.completed label {color: #d9d9d9;text-decoration: line-through;
        }.todo-list li .destroy {display: none;position: absolute;top: 0;right: 10px;bottom: 0;width: 40px;height: 40px;margin: auto 0;font-size: 30px;color: #cc9a9a;margin-bottom: 11px;transition: color 0.2s ease-out;
        }.todo-list li .destroy:hover {color: #af5b5e;
        }.todo-list li .destroy:after {content: '×';
        }.todo-list li:hover .destroy {display: block;
        }.todo-list li .edit {display: none;
        }.todo-list li.editing:last-child {margin-bottom: -1px;
        }.footer {color: #777;padding: 10px 15px;height: 20px;text-align: center;border-top: 1px solid #e6e6e6;
        }.footer:before {content: '';position: absolute;right: 0;bottom: 0;left: 0;height: 50px;overflow: hidden;box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),0 8px 0 -3px #f6f6f6,0 9px 1px -3px rgba(0, 0, 0, 0.2),0 16px 0 -6px #f6f6f6,0 17px 2px -6px rgba(0, 0, 0, 0.2);
        }.todo-count {float: left;text-align: left;
        }.todo-count strong {font-weight: 300;
        }.filters {margin: 0;padding: 0;list-style: none;position: absolute;right: 0;left: 0;
        }.filters li {display: inline;
        }.filters li a {color: inherit;margin: 3px;padding: 3px 7px;text-decoration: none;border: 1px solid transparent;border-radius: 3px;
        }.filters li a.selected,
        .filters li a:hover {border-color: rgba(175, 47, 47, 0.1);
        }.filters li a.selected {border-color: rgba(175, 47, 47, 0.2);
        }.clear-completed,
        html .clear-completed:active {float: right;position: relative;line-height: 20px;text-decoration: none;cursor: pointer;
        }.clear-completed:hover {text-decoration: underline;
        }.info {margin: 65px auto 0;color: #bfbfbf;font-size: 10px;text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);text-align: center;
        }.info p {line-height: 1;
        }.info a {color: inherit;text-decoration: none;font-weight: 400;
        }.info a:hover {text-decoration: underline;
        }/*Hack to remove background from Mobile Safari.Can't use it globally since it destroys checkboxes in Firefox
        */
        @media screen and (-webkit-min-device-pixel-ratio:0) {.toggle-all,.todo-list li .toggle {background: none;}.todo-list li .toggle {height: 40px;}.toggle-all {-webkit-transform: rotate(90deg);transform: rotate(90deg);-webkit-appearance: none;appearance: none;}
        }@media (max-width: 430px) {.footer {height: 50px;}.filters {bottom: 10px;}
        }
        

4. 总结

到这里我们就使用 Angular 2 创建了一个 TODO MVC 项目。让我们一起回顾下,本文以后我们都学习到了什么:

  • 使用 Angular CLI 创建并初始化一个 Angular 项目。
  • 使用 Angular CLI 创建 Todo 对象,TodoService 并实现里面的逻辑代码。
  • 使用 ng test 测试我们 TodoService 的逻辑代码
  • 对 Angular 模版语法有了一定的了解,属性绑定,事件绑定,双向绑定等。
  • 对 Angular 组件有一定的了解,组件装饰器里的元数据与模版和样式文件关联,组件与模版的通过绑定进行交互,组件通过元数据和构造函数注入服务。

转载于:https://my.oschina.net/bluesummer/blog/968446

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 刚割完双眼皮能干嘛

    ...

    2024/4/20 18:40:04
  2. 芳艺芳艺双眼皮多少钱

    ...

    2024/4/20 18:40:04
  3. 二甲医院能做双眼皮吗

    ...

    2024/4/22 18:45:38
  4. Grafana 的插件开发

    <1>推荐一个网址&#xff1a;http://blog.leanote.com/post/nixon/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91 Grafana Panel Plugin 开发 Grafana 插件开发 上一次分享提到过Grafana的插件氛围三种类型(Panel, Datasource, App),这一次主要记录Panel类型的插件开发. 0. …...

    2024/4/20 18:40:01
  5. 一个基于highcharts的angular小插件

    2019独角兽企业重金招聘Python工程师标准>>> 最近要频繁使用表格,然后就想到了在angular项目上自己做一个插件,不至于我每次都要自己写好多重复的highcharts定义,那么接下来就直接上代码, 首先当然是html的结构: <!DOCTYPE html> <html lang"en"…...

    2024/5/1 15:09:36
  6. 东莞双眼皮华美心细

    ...

    2024/5/2 9:47:57
  7. 华为vrp下的接口类型

    华为的环回中,serial接口默认是ppp,以太网接口对应borad. ospf netwrok-type 修改网络类型 display ospf int //查看接口。 华为的认证 链路级: 接口下 ospf authentication-mode null/md5/simple/hmac-md5 //基于散列信息码 ospf authentication-mode md5 1 cipher cisco /…...

    2024/4/20 18:39:58
  8. 东莞双眼皮华美满意

    ...

    2024/5/2 10:31:40
  9. 东莞双眼皮华美独家

    ...

    2024/5/2 10:46:26
  10. 东莞双眼皮多少钱2017

    ...

    2024/5/2 12:56:58
  11. 东莞割双眼皮华美心细

    ...

    2024/4/20 18:39:54
  12. 东莞割双眼皮华美推荐

    ...

    2024/4/20 17:43:05
  13. 东莞割双眼皮华美适宜

    ...

    2024/4/21 7:58:33
  14. 大明星都在哪割丹凤眼单眼皮德州整形医院点东莞割双眼皮华美顶尖

    ...

    2024/4/21 7:58:31
  15. 一名SM是怎么炼成的(之一锻炼领导力)

    领导力分享要点内容记录领导力可以学习吗? 在我们的常规认知中,“领导力”被神化为一种“感觉”,似乎无法通过学习学会。领导力可以学会吗?很多人会摇头,这是东西方观念上的根本差别:大家都知道孔子(我们的万世师表),但是大家知道孔子最大的弱点是什么吗?这个人是食古…...

    2024/4/21 7:58:31
  16. 大连谁双眼皮做的好

    ...

    2024/4/21 7:58:30
  17. 关于Angular Component changeDetection策略设置成OnPush的一个单元测试局限性

    局限性&#xff1a;如果Component的changeDetection的值为ChangeDetectionStrategy.OnPush而不是Default&#xff0c;那么fixture.detectChanges()只有在一个test spec里第一次调用才会生效。 这是Angular一个已知的bug&#xff1a;https://github.com/angular/angular/issue…...

    2024/4/21 7:58:29
  18. lwip-2.1.2的裸机移植(STM32F1 + SPL库 + lwip-2.1.2 + ENC28J60)

    试验原因 产品板子上用的LWIP版本较旧,这次准备换成现在官方最新的lwip-2.1.2. 想重新作lwip移植的原因 : 产品板子有bug与lwip相关,应该是以前程序移植的lwip有问题(配置和使用lwip). 正好这次放长假, 仔细研究一下lwip的移植, 配置,使用,调试。 lwip中带调试日志,可以通…...

    2024/5/2 5:21:26
  19. 大连哪里做大连哪做大连双眼皮加开眼角

    ...

    2024/4/21 7:58:28
  20. angular中组件changeDetection为ChangeDetectionStrategy.OnPush时的学习

    注&#xff1a;我用的angular 8 一个angular应用是由组件树组成的&#xff0c;changeDetection是其中比较深的部分&#xff0c;我也不懂哈。 angular中changeDetection中的策略有这样的描述&#xff1a; 总而言之&#xff0c;对于一个组件而言&#xff0c;2中changeDetectio…...

    2024/4/21 7:58:25

最新文章

  1. CAN测试工具

    CAN测试工具是用于测试CAN&#xff08;Controller Area Network&#xff09;总线通信的软件工具。这些工具主要用于汽车电子控制系统、工业现场、电梯控制系统、电力通讯、安防监控系统、船舶运输、轨道交通、医疗设备、纺织机械、楼宇控制等监控系统的开发和测试。 常见的CAN…...

    2024/5/2 18:42:39
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 【LeetCode热题100】【二叉树】二叉树的中序遍历

    题目链接&#xff1a;94. 二叉树的中序遍历 - 力扣&#xff08;LeetCode&#xff09; 中序遍历就是先遍历左子树再遍历根最后遍历右子树 class Solution { public:void traverse(TreeNode *root) {if (!root)return;traverse(root->left);ans.push_back(root->val);tra…...

    2024/4/29 11:15:33
  4. 迭代实现二叉树的遍历-算法通关村

    迭代实现二叉树的遍历-算法通关村 理论上&#xff0c;递归能做的迭代一定能做&#xff0c;但可能会比较复杂。有时候面试官要求不使用递归实现三种遍历&#xff0c;递归就是每次执行方法调用都会先把当前的局部变量、参数值和返回地址等压入栈中&#xff0c;后面在递归返回的时…...

    2024/5/1 14:58:08
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/2 9:28:15
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57