* ngIf Вопрос о сроках обновления DOM в Angular

Я пытаюсь объяснить эту проблему шаг за шагом в следующем примере.

0) Question

Я пытаюсь спросить вас вот так:

я хочу чтобы открыть страницу, например, facebook profile www.facebook.com/kaila.piyush

, получить идентификатор от url и проанализировать его на файл profile.php и вернуть данные из базы данных и показать пользователю его профиль

обычно, когда мы разрабатываем любой веб-сайт, его ссылка выглядит как www.website.com/profile.php?id=username example.com/weblog/index.php?y=2000&m=11&d=23&id = 5678

Теперь мы обновляем новый стиль, не переписываем, мы используем www.website.com/username или example.com/weblog/2000/11/23/5678 как permalink

http://example.com/profile/userid (get a profile by the ID) 
http://example.com/profile/username (get a profile by the username) 
http://example.com/myprofile (get the profile of the currently logged-in user)

1) .htaccess

Создайте файл .htaccess в корневой папке или обновите существующий:

Options +FollowSymLinks
# Turn on the RewriteEngine
RewriteEngine On
#  Rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php

Что это делает?

Если запрос предназначен для реального каталога или файла (который существует на сервере), index.php не обслуживается, иначе каждый URL перенаправляется на index.php.

2) index.php

Теперь мы хотим знать, что t для запуска, поэтому нам нужно прочитать URL:

В index.php:

// index.php    

// This is necessary when index.php is not in the root folder, but in some subfolder...
// We compare $requestURL and $scriptName to remove the inappropriate values
$requestURI = explode(‘/’, $_SERVER[‘REQUEST_URI’]);
$scriptName = explode(‘/’,$_SERVER[‘SCRIPT_NAME’]);

for ($i= 0; $i < sizeof($scriptName); $i++)
{
    if ($requestURI[$i] == $scriptName[$i])
    {
        unset($requestURI[$i]);
    }
}

$command = array_values($requestURI);
With the url http://example.com/profile/19837, $command would contain :

$command = array(
    [0] => 'profile',
    [1] => 19837,
    [2] => ,
)
Now, we have to dispatch the URLs. We add this in the index.php :

// index.php

require_once("profile.php"); // We need this file
switch($command[0])
{
    case ‘profile’ :
        // We run the profile function from the profile.php file.
        profile($command([1]);
        break;
    case ‘myprofile’ :
        // We run the myProfile function from the profile.php file.
        myProfile();
        break;
    default:
        // Wrong page ! You could also redirect to your custom 404 page.
        echo "404 Error : wrong page.";
        break;
}

2) profile.php

Теперь в profile.php, мы должны иметь что-то вроде этого:

// profile.php

function profile($chars)
{
    // We check if $chars is an Integer (ie. an ID) or a String (ie. a potential username)

    if (is_int($chars)) {
        $id = $chars;
        // Do the SQL to get the $user from his ID
        // ........
    } else {
        $username = mysqli_real_escape_string($char);
        // Do the SQL to get the $user from his username
        // ...........
    }

    // Render your view with the $user variable
    // .........
}

function myProfile()
{
    // Get the currently logged-in user ID from the session :
    $id = ....

    // Run the above function :
    profile($id);
}
3
задан DongBin Kim 13 July 2018 в 05:58
поделиться

2 ответа

Вы можете переместить стиль в шаблон и дать ему динамическое значение. Метод calculateLeft вызывается только тогда, когда действительный #tooltip находится в DOM.

Также обратите внимание, что в этом случае нет необходимости в ViewChild или Renderer2:

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

@Component({
  ...
})
export class AComponent {
    show: boolean;
    lastOffsetX: number;

    public methodA(e: MouseEvent): void {
        this.show = true;
        this.lastOffsetX = e.offsetX;
    }

    public calculateLeft(tooltip) {
        return (this.lastOffsetX - tooltip.offsetWidth) + 'px';
    }
}

И HTML:

<ng-container *ngIf="show">
    <div #tooltip [ngStyle]="{left: calculateLeft(tooltip)}">
        Hello
    </div>
</ng-container>
<button (click)="methodA($event)">Click me</button>
1
ответ дан MondKin 17 August 2018 в 13:38
поделиться
  • 1
    Простой и понятный! Спасибо огромное! – DongBin Kim 13 July 2018 в 16:40
  • 2
    Я пробовал этот подход, но он дает мне эту ошибку: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Я предполагаю, что это потому, что метод A вызывается непрерывно (в моем приложении оно вызвано событием mouseover, а не в событии click), – DongBin Kim 16 July 2018 в 02:52
  • 3
    Это исключение может произойти, если вы измените поле родителя внутри дочернего компонента. Но мне нужно будет увидеть фактический фрагмент кода, чтобы указать, откуда возникла проблема. – MondKin 16 July 2018 в 17:02

Попробуйте this.ref.detectChanges (), импортировав ChangeDetectorRef угловой, чтобы заставить DOM обнаружить изменения. Вот документация для того же: https://angular.io/api/core/ChangeDetectorRef

-1
ответ дан Code_maniac 17 August 2018 в 13:38
поделиться
  • 1
    Это может сработать, но я не хочу ссылаться на обнаружение изменений вручную, потому что метод, который я реализую, вызывается непрерывно, и обнаружение изменений будет вызвано слишком много раз. – DongBin Kim 13 July 2018 в 06:11
  • 2
    Иногда это так, как мы можем обнаружить переменные, которые иначе не воспринимаются сами по себе. Вы можете поместить условие, чтобы проверить, является ли element.length == 0 и только затем вызывает это, чтобы избежать его многократно. – Code_maniac 13 July 2018 в 07:11
Другие вопросы по тегам:

Похожие вопросы: