Maison interface Web js tutoriel Explication détaillée de l'utilisation d'Angular Renderer

Explication détaillée de l'utilisation d'Angular Renderer

May 14, 2018 pm 01:49 PM
angular 详解

Cette fois, je vais vous apporter une explication détaillée de l'utilisation du moteur de rendu Angular Renderer. Quelles sont les précautions lors de l'utilisation du moteur de rendu Angular Renderer. Voici un cas pratique, jetons un coup d'œil.

L'un des objectifs de conception d'Angular est de rendre le navigateur indépendant du DOM. Le DOM est complexe, donc en séparer les composants rendra nos applications plus faciles à tester et à refactoriser. Un autre avantage est que grâce à ce découplage, nos applications peuvent fonctionner sur d'autres plateformes (telles que Node.js, WebWorkers, NativeScript, etc.).

Afin de prendre en charge plusieurs plates-formes, Angular encapsule les différences des différentes plates-formes à travers des couches d'abstraction. Par exemple, la classe abstraite Renderer, Renderer2, la classe abstraite RootRenderer, etc. sont définies. De plus, les types de référence suivants sont définis : ElementRef, TemplateRef, ViewRef, ComponentRef, ViewContainerRef, etc.

Le contenu principal de cet article est d'analyser le moteur de rendu en Angular, mais avant de procéder à l'analyse spécifique, introduisons d'abord le concept de plateforme.

Plateforme

Qu'est-ce qu'une plate-forme

Une plate-forme est l'environnement dans lequel les applications s'exécutent . Il s'agit d'un ensemble de services qui peuvent être utilisés pour accéder aux fonctionnalités intégrées de votre application et au framework Angular lui-même. Étant donné qu'Angular est avant tout un framework d'interface utilisateur, l'une des fonctionnalités les plus importantes fournies par la plateforme est le rendu des pages.

Plateforme et application d'amorçage

Avant de commencer à créer un moteur de rendu personnalisé, examinons la configuration de la plate-forme et le démarrage de l'application.

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
@NgModule({
 imports: [BrowserModule],
 bootstrap: [AppCmp]
})
class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);
Copier après la connexion

Comme vous pouvez le constater, le processus d'amorçage se compose de deux parties : la création de la plateforme et l'amorçage du module. Dans cet exemple, nous importons le module BrowserModule, qui fait partie de la plateforme du navigateur. Il ne peut y avoir qu'une seule plateforme activée dans l'application, mais nous pouvons l'utiliser pour amorcer plusieurs modules, comme indiqué ci-dessous :

const platformRef: PlatformRef = platformBrowserDynamic();
platformRef.bootstrapModule(AppModule1);
platformRef.bootstrapModule(AppModule2);
Copier après la connexion

Puisqu'il ne peut y avoir qu'une seule plateforme activée dans l'application, le service singleton doit Inscrivez-vous sur la plateforme. Par exemple, le navigateur n'a qu'une seule barre d'adresse et l'objet de service correspondant est un singleton. De plus, comment afficher notre interface utilisateur personnalisée dans le navigateur nécessite l'utilisation du moteur de rendu fourni par Angular.

Renderer

Qu'est-ce qu'un renderer

Le renderer est fourni par Angular pour nous A service intégré qui effectue des opérations de rendu de l'interface utilisateur. Dans un navigateur, le rendu est le processus de mappage d'un modèle à une vue. Les valeurs du modèle peuvent être des types de données primitifs en JavaScript, des objets, des tableaux ou d'autres objets de données. Cependant, les vues peuvent être d'autres éléments tels que des paragraphes, des formulaires, des boutons, etc. sur la page. Ces éléments de page sont représentés en interne par DOM (Document Object Model).

Rendu angulaire

RootRenderer

export abstract class RootRenderer {
 abstract renderComponent(componentType: RenderComponentType): Renderer;
}
Copier après la connexion
Renderer

/**
 * @deprecated Use the `Renderer2` instead.
 */
export abstract class Renderer {
 abstract createElement(parentElement: any, name: string, 
 debugInfo?: RenderDebugInfo): any;
 abstract createText(parentElement: any, value: string, 
 debugInfo?: RenderDebugInfo): any;
 abstract listen(renderElement: any, name: string, callback: Function): Function;
 abstract listenGlobal(target: string, name: string, callback: Function): Function;
 abstract setElementProperty(renderElement: any, propertyName: string, propertyValue: 
 any): void;
 abstract setElementAttribute(renderElement: any, attributeName: string, 
 attributeValue: string): void;
 // ...
}
Copier après la connexion
Renderer2

export abstract class Renderer2 {
 abstract createElement(name: string, namespace?: string|null): any;
 abstract createComment(value: string): any;
 abstract createText(value: string): any;
 abstract setAttribute(el: any, name: string, value: string,
 namespace?: string|null): void;
 abstract removeAttribute(el: any, name: string, namespace?: string|null): void;
 abstract addClass(el: any, name: string): void;
 abstract removeClass(el: any, name: string): void;
 abstract setStyle(el: any, style: string, value: any, 
 flags?: RendererStyleFlags2): void;
 abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void;
 abstract setProperty(el: any, name: string, value: any): void;
 abstract setValue(node: any, value: string): void;
 abstract listen(
  target: 'window'|'document'|'body'|any, eventName: string,
  callback: (event: any) => boolean | void): () => void;
}
Copier après la connexion
A noter que dans la version Angular 4.x+, nous utilisons

au lieu de Renderer2. En observant les classes abstraites liées à Renderer (Renderer, Renderer2), nous avons constaté qu'il existe de nombreuses méthodes abstraites définies dans la classe abstraite, qui sont utilisées pour créer des éléments, du texte, définir des attributs, ajouter des styles et définir l'écoute d'événements, etc. Renderer

Comment fonctionnent les moteurs de rendu

Lors de l'instanciation d'un composant, Angular appelle la méthode

et associe le moteur de rendu qu'il obtient à cette instance de composant. Angular effectuera les opérations correspondantes via le moteur de rendu lors du rendu du composant, telles que la création d'éléments, la définition de propriétés, l'ajout de styles et l'abonnement à des événements. renderComponent()

Utilisation de Renderer

@Component({
 selector: 'exe-cmp',
 template: `
 <h3>Exe Component</h3>
 `
})
export class ExeComponent {
 constructor(private renderer: Renderer2, elRef: ElementRef) {
 this.renderer.setProperty(elRef.nativeElement, 'author', 'semlinker');
 }
}
Copier après la connexion
Dans le code ci-dessus, nous utilisons l'injection de constructeur pour injecter les instances Renderer2 et ElementRef. Certains lecteurs peuvent se demander comment l'objet instance injecté est généré. Nous ne présentons ici que brièvement les connaissances pertinentes et n'entrerons pas dans les détails. Le code spécifique est le suivant :

TokenKey

// packages/core/src/view/util.ts
const _tokenKeyCache = new Map<any, string>();
export function tokenKey(token: any): string {
 let key = _tokenKeyCache.get(token);
 if (!key) {
 key = stringify(token) + '_' + _tokenKeyCache.size;
 _tokenKeyCache.set(token, key);
 }
 return key;
}
// packages/core/src/view/provider.ts
const RendererV1TokenKey = tokenKey(RendererV1);
const Renderer2TokenKey = tokenKey(Renderer2);
const ElementRefTokenKey = tokenKey(ElementRef);
const ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
const TemplateRefTokenKey = tokenKey(TemplateRef);
const ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
const InjectorRefTokenKey = tokenKey(Injector);
Copier après la connexion
resolveDep()

export function resolveDep(
 view: ViewData, elDef: NodeDef, 
 allowPrivateServices: boolean, depDef: DepDef,
 notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
 const tokenKey = depDef.tokenKey;
 // ...
 while (view) {
 if (elDef) {
  switch (tokenKey) {
  case RendererV1TokenKey: { // tokenKey(RendererV1)
   const compView = findCompView(view, elDef, allowPrivateServices);
   return createRendererV1(compView);
  }
  case Renderer2TokenKey: { // tokenKey(Renderer2)
   const compView = findCompView(view, elDef, allowPrivateServices);
   return compView.renderer;
  }
  case ElementRefTokenKey: // tokenKey(ElementRef)
   return new ElementRef(asElementData(view, elDef.index).renderElement);
   // ... 此外还包括:ViewContainerRefTokenKey、TemplateRefTokenKey、
  // ChangeDetectorRefTokenKey 等
  }
 }
 }
 // ...
}
Copier après la connexion

通过以上代码,我们发现当我们在组件类的构造函数中声明相应的依赖对象时,如 Renderer2 和 ElementRef,Angular 内部会调用 resolveDep() 方法,实例化 Token 对应依赖对象。

在大多数情况下,我们开发的 Angular 应用程序是运行在浏览器平台,接下来我们来了解一下该平台下的默认渲染器 - DefaultDomRenderer2。

DefaultDomRenderer2

在浏览器平台下,我们可以通过调用 DomRendererFactory2 工厂,根据不同的视图封装方案,创建对应渲染器。

DomRendererFactory2

// packages/platform-browser/src/dom/dom_renderer.ts
@Injectable()
export class DomRendererFactory2 implements RendererFactory2 {
 private rendererByCompId = new Map<string, Renderer2>();
 private defaultRenderer: Renderer2;
 constructor(
 private eventManager: EventManager, 
 private sharedStylesHost: DomSharedStylesHost) {
 // 创建默认的DOM渲染器
 this.defaultRenderer = new DefaultDomRenderer2(eventManager);
 };
 createRenderer(element: any, type: RendererType2|null): Renderer2 {
 if (!element || !type) {
  return this.defaultRenderer;
 }
 // 根据不同的视图封装方案,创建不同的渲染器
 switch (type.encapsulation) {
  // 无 Shadow DOM,但是通过 Angular 提供的样式包装机制来封装组件,
  // 使得组件的样式不受外部影响,这是 Angular 的默认设置。
  case ViewEncapsulation.Emulated: {
  let renderer = this.rendererByCompId.get(type.id);
  if (!renderer) {
   renderer =
    new EmulatedEncapsulationDomRenderer2(this.eventManager, 
     this.sharedStylesHost, type);
   this.rendererByCompId.set(type.id, renderer);
  }
  (<EmulatedEncapsulationDomRenderer2>renderer).applyToHost(element);
  return renderer;
  }
  // 使用原生的 Shadow DOM 特性 
  case ViewEncapsulation.Native:
  return new ShadowDomRenderer(this.eventManager, 
   this.sharedStylesHost, element, type);
  // 无 Shadow DOM,并且也无样式包装
  default: {
  // ...
  return this.defaultRenderer;
  }
 }
 }
}
Copier après la connexion

上面代码中的 EmulatedEncapsulationDomRenderer2ShadowDomRenderer 类都继承于 DefaultDomRenderer2 类,接下来我们再来看一下 DefaultDomRenderer2 类的内部实现:

class DefaultDomRenderer2 implements Renderer2 { 
 constructor(private eventManager: EventManager) {}
 // 省略 Renderer2 抽象类中定义的其它方法
 createElement(name: string, namespace?: string): any {
 if (namespace) {
  return document.createElementNS(NAMESPACE_URIS[namespace], name);
 }
 return document.createElement(name);
 }
 createComment(value: string): any { return document.createComment(value); }
 createText(value: string): any { return document.createTextNode(value); }
 addClass(el: any, name: string): void { el.classList.add(name); }
 setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
 if (flags & RendererStyleFlags2.DashCase) {
  el.style.setProperty(
   style, value, !!(flags & RendererStyleFlags2.Important) ? 'important' : '');
 } else {
  el.style[style] = value;
 }
 }
 listen(
 target: 'window'|'document'|'body'|any, 
 event: string, 
 callback: (event: any) => boolean):
  () => void {
 checkNoSyntheticProp(event, 'listener');
 if (typeof target === 'string') {
  return <() => void>this.eventManager.addGlobalEventListener(
   target, event, decoratePreventDefault(callback));
 }
 return <() => void>this.eventManager.addEventListener(
   target, event, decoratePreventDefault(callback)) as() => void;
 }
}
Copier après la connexion

介绍完 DomRendererFactory2DefaultDomRenderer2 类,最后我们来看一下 Angular 内部如何利用它们。

DomRendererFactory2 内部应用

BrowserModule

// packages/platform-browser/src/browser.ts
@NgModule({
 providers: [
 // 配置 DomRendererFactory2 和 RendererFactory2 provider
 DomRendererFactory2,
 {provide: RendererFactory2, useExisting: DomRendererFactory2},
 // ...
 ],
 exports: [CommonModule, ApplicationModule]
})
export class BrowserModule {
 constructor(@Optional() @SkipSelf() parentModule: BrowserModule) {
 // 用于判断应用中是否已经导入BrowserModule模块
 if (parentModule) {
  throw new Error(
  `BrowserModule has already been loaded. If you need access to common 
  directives such as NgIf and NgFor from a lazy loaded module, 
  import CommonModule instead.`);
 }
 }
}
Copier après la connexion

createComponentView()

// packages/core/src/view/view.ts
export function createComponentView(
 parentView: ViewData, 
 nodeDef: NodeDef, 
 viewDef: ViewDefinition, 
 hostElement: any): ViewData {
 const rendererType = nodeDef.element !.componentRendererType; // 步骤一
 let compRenderer: Renderer2;
 if (!rendererType) { // 步骤二
 compRenderer = parentView.root.renderer;
 } else {
 compRenderer = parentView.root.rendererFactory
  .createRenderer(hostElement, rendererType);
 }
 
 return createView(
 parentView.root, compRenderer, parentView, 
  nodeDef.element !.componentProvider, viewDef);
}
Copier après la connexion

步骤一

当 Angular 在创建组件视图时,会根据 nodeDef.element 对象的 componentRendererType 属性值,来创建组件的渲染器。接下来我们先来看一下 NodeDefElementDefRendererType2 接口定义:

// packages/core/src/view/types.ts
// 视图中节点的定义
export interface NodeDef {
 bindingIndex: number;
 bindings: BindingDef[];
 bindingFlags: BindingFlags;
 outputs: OutputDef[];
 element: ElementDef|null; // nodeDef.element
 provider: ProviderDef|null;
 // ...
}
// 元素的定义
export interface ElementDef {
 name: string|null;
 attrs: [string, string, string][]|null;
 template: ViewDefinition|null;
 componentProvider: NodeDef|null;
 // 设置组件渲染器的类型
 componentRendererType: RendererType2|null; // nodeDef.element.componentRendererType
 componentView: ViewDefinitionFactory|null;
 handleEvent: ElementHandleEventFn|null;
 // ...
}
// packages/core/src/render/api.ts
// RendererType2 接口定义
export interface RendererType2 {
 id: string;
 encapsulation: ViewEncapsulation; // Emulated、Native、None
 styles: (string|any[])[];
 data: {[kind: string]: any};
}
Copier après la connexion

步骤二

获取 componentRendererType 的属性值后,如果该值为 null 的话,则直接使用 parentView.root 属性值对应的 renderer 对象。若该值不为空,则调用 parentView.root 对象的 rendererFactory() 方法创建 renderer 对象。

通过上面分析,我们发现不管走哪条分支,我们都需要使用 parentView.root 对象,然而该对象是什么特殊对象?我们发现 parentView 的数据类型是 ViewData ,该数据接口定义如下:

// packages/core/src/view/types.ts
export interface ViewData {
 def: ViewDefinition;
 root: RootData;
 renderer: Renderer2;
 nodes: {[key: number]: NodeData};
 state: ViewState;
 oldValues: any[];
 disposables: DisposableFn[]|null;
 // ...
}
Copier après la connexion

通过 ViewData 的接口定义,我们终于发现了 parentView.root 的属性类型,即 RootData

// packages/core/src/view/types.ts
export interface RootData {
 injector: Injector;
 ngModule: NgModuleRef<any>;
 projectableNodes: any[][];
 selectorOrNode: any;
 renderer: Renderer2;
 rendererFactory: RendererFactory2;
 errorHandler: ErrorHandler;
 sanitizer: Sanitizer;
}
Copier après la connexion

那好,现在问题来了:

  1. 什么时候创建 RootData 对象?

  2. 怎么创建 RootData 对象?

什么时候创建 RootData 对象?

当创建根视图的时候会创建 RootData,在开发环境会调用 debugCreateRootView() 方法创建 RootView,而在生产环境会调用 createProdRootView() 方法创建 RootView。简单起见,我们只分析 createProdRootView() 方法:

function createProdRootView(
 elInjector: Injector, 
 projectableNodes: any[][], 
 rootSelectorOrNode: string | any,
 def: ViewDefinition, 
 ngModule: NgModuleRef<any>, 
 context?: any): ViewData {
 /** RendererFactory2 Provider 配置
 * DomRendererFactory2,
 * {provide: RendererFactory2, useExisting: DomRendererFactory2},
 */
 const rendererFactory: RendererFactory2 = ngModule.injector.get(RendererFactory2);
  
 return createRootView(
  createRootData(elInjector, ngModule, rendererFactory,
  projectableNodes, rootSelectorOrNode),
  def, context);
}
// 创建根视图
export function createRootView(root: RootData, def: ViewDefinition, 
 context?: any): ViewData {
 // 创建ViewData对象
 const view = createView(root, root.renderer, null, null, def);
 initView(view, context, context);
 createViewNodes(view);
 return view;
}
Copier après la connexion

上面代码中,当创建 RootView 的时候,会调用 createRootData() 方法创建 RootData 对象。最后一步就是分析 createRootData() 方法。

怎么创建 RootData 对象?

通过上面分析,我们知道通过 createRootData() 方法,来创建 RootData 对象。createRootData() 方法具体实现如下:

function createRootData(
 elInjector: Injector, 
 ngModule: NgModuleRef<any>, 
 rendererFactory: RendererFactory2,
 projectableNodes: any[][], 
 rootSelectorOrNode: any): RootData {
 const sanitizer = ngModule.injector.get(Sanitizer);
 const errorHandler = ngModule.injector.get(ErrorHandler);
 // 创建RootRenderer
 const renderer = rendererFactory.createRenderer(null, null); 
 return {
 ngModule,
 injector: elInjector,
 projectableNodes,
 selectorOrNode: rootSelectorOrNode, 
 sanitizer, 
 rendererFactory, 
 renderer,
 errorHandler
 };
}
Copier après la connexion

此时浏览器平台下, Renderer 渲染器的相关基础知识已介绍完毕。接下来,我们做一个简单总结:

  1. Angular 应用程序启动时会创建 RootView (生产环境下通过调用 createProdRootView() 方法)

  2. 创建 RootView 的过程中,会创建 RootData 对象,该对象可以通过 ViewData 的 root 属性访问到。基于 RootData 对象,我们可以通过 renderer 访问到默认的渲染器,即 DefaultDomRenderer2 实例,此外也可以通过 rendererFactory 访问到 RendererFactory2 实例。

  3. 在创建组件视图 (ViewData) 时,会根据 componentRendererType 的属性值,来设置组件关联的 renderer 渲染器。

  4. Lors du rendu d'une vue de composant, Angular utilisera l'API fournie par renderer associée au composant pour créer des nœuds dans la vue ou effectuer des opérations liées à la vue, telles que la création d'éléments (createElement), Créez du texte (createText), définissez le style (setStyle) et définissez l'écoute des événements (écouter), etc.

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Explication détaillée des avantages et des inconvénients de l'utilisation du chemin Webpack et de publicPath

JS+HTML5 pour créer une animation de flux de particules liées à la souris

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Explication détaillée de la fonction mode en C++ Explication détaillée de la fonction mode en C++ Nov 18, 2023 pm 03:08 PM

Explication détaillée de la fonction mode en C++ En statistiques, le mode fait référence à la valeur qui apparaît le plus fréquemment dans un ensemble de données. En langage C++, nous pouvons trouver le mode dans n’importe quel ensemble de données en écrivant une fonction de mode. La fonction mode peut être implémentée de nombreuses manières différentes, deux des méthodes couramment utilisées seront présentées en détail ci-dessous. La première méthode consiste à utiliser une table de hachage pour compter le nombre d'occurrences de chaque nombre. Tout d’abord, nous devons définir une table de hachage avec chaque nombre comme clé et le nombre d’occurrences comme valeur. Ensuite, pour un ensemble de données donné, nous exécutons

Explication détaillée de l'obtention des droits d'administrateur dans Win11 Explication détaillée de l'obtention des droits d'administrateur dans Win11 Mar 08, 2024 pm 03:06 PM

Le système d'exploitation Windows est l'un des systèmes d'exploitation les plus populaires au monde et sa nouvelle version Win11 a beaucoup attiré l'attention. Dans le système Win11, l'obtention des droits d'administrateur est une opération importante. Les droits d'administrateur permettent aux utilisateurs d'effectuer davantage d'opérations et de paramètres sur le système. Cet article présentera en détail comment obtenir les autorisations d'administrateur dans le système Win11 et comment gérer efficacement les autorisations. Dans le système Win11, les droits d'administrateur sont divisés en deux types : administrateur local et administrateur de domaine. Un administrateur local dispose de tous les droits d'administration sur l'ordinateur local

Comment installer Angular sur Ubuntu 24.04 Comment installer Angular sur Ubuntu 24.04 Mar 23, 2024 pm 12:20 PM

Angular.js est une plateforme JavaScript librement accessible pour créer des applications dynamiques. Il vous permet d'exprimer rapidement et clairement divers aspects de votre application en étendant la syntaxe HTML en tant que langage de modèle. Angular.js fournit une gamme d'outils pour vous aider à écrire, mettre à jour et tester votre code. De plus, il offre de nombreuses fonctionnalités telles que le routage et la gestion des formulaires. Ce guide expliquera comment installer Angular sur Ubuntu24. Tout d’abord, vous devez installer Node.js. Node.js est un environnement d'exécution JavaScript basé sur le moteur ChromeV8 qui vous permet d'exécuter du code JavaScript côté serveur. Être à Ub

Explication détaillée du fonctionnement de la division dans Oracle SQL Explication détaillée du fonctionnement de la division dans Oracle SQL Mar 10, 2024 am 09:51 AM

Explication détaillée de l'opération de division dans OracleSQL Dans OracleSQL, l'opération de division est une opération mathématique courante et importante, utilisée pour calculer le résultat de la division de deux nombres. La division est souvent utilisée dans les requêtes de bases de données. Comprendre le fonctionnement de la division et son utilisation dans OracleSQL est donc l'une des compétences essentielles des développeurs de bases de données. Cet article discutera en détail des connaissances pertinentes sur les opérations de division dans OracleSQL et fournira des exemples de code spécifiques pour référence aux lecteurs. 1. Opération de division dans OracleSQL

Explication détaillée de la fonction reste en C++ Explication détaillée de la fonction reste en C++ Nov 18, 2023 pm 02:41 PM

Explication détaillée de la fonction reste en C++ En C++, l'opérateur reste (%) est utilisé pour calculer le reste de la division de deux nombres. Il s'agit d'un opérateur binaire dont les opérandes peuvent être n'importe quel type entier (y compris char, short, int, long, etc.) ou un type nombre à virgule flottante (tel que float, double). L'opérateur reste renvoie un résultat du même signe que le dividende. Par exemple, pour l'opération de reste des entiers, nous pouvons utiliser le code suivant pour implémenter : inta=10;intb=3;

Explication détaillée du rôle et de l'utilisation de l'opérateur modulo PHP Explication détaillée du rôle et de l'utilisation de l'opérateur modulo PHP Mar 19, 2024 pm 04:33 PM

L'opérateur modulo (%) en PHP est utilisé pour obtenir le reste de la division de deux nombres. Dans cet article, nous discuterons en détail du rôle et de l'utilisation de l'opérateur modulo et fournirons des exemples de code spécifiques pour aider les lecteurs à mieux comprendre. 1. Le rôle de l'opérateur modulo En mathématiques, lorsqu'on divise un entier par un autre entier, on obtient un quotient et un reste. Par exemple, lorsque l’on divise 10 par 3, le quotient est 3 et le reste est 1. L'opérateur modulo est utilisé pour obtenir ce reste. 2. Utilisation de l'opérateur modulo En PHP, utilisez le symbole % pour représenter le module

Composants angulaires et leurs propriétés d'affichage : comprendre les valeurs par défaut non bloquantes Composants angulaires et leurs propriétés d'affichage : comprendre les valeurs par défaut non bloquantes Mar 15, 2024 pm 04:51 PM

Le comportement d'affichage par défaut des composants du framework Angular ne concerne pas les éléments au niveau du bloc. Ce choix de conception favorise l'encapsulation des styles de composants et encourage les développeurs à définir consciemment la manière dont chaque composant est affiché. En définissant explicitement l'affichage des propriétés CSS, l'affichage des composants angulaires peut être entièrement contrôlé pour obtenir la mise en page et la réactivité souhaitées.

Explication détaillée de la fonction d'appel système Linux system() Explication détaillée de la fonction d'appel système Linux system() Feb 22, 2024 pm 08:21 PM

Explication détaillée de la fonction d'appel système Linux system() L'appel système est une partie très importante du système d'exploitation Linux. Il fournit un moyen d'interagir avec le noyau système. Parmi elles, la fonction system() est l’une des fonctions d’appel système couramment utilisées. Cet article présentera en détail l’utilisation de la fonction system() et fournira des exemples de code correspondants. Concepts de base des appels système Les appels système sont un moyen permettant aux programmes utilisateur d'interagir avec le noyau du système d'exploitation. Les programmes utilisateur demandent au système d'exploitation en appelant des fonctions d'appel système

See all articles