>  기사  >  CMS 튜토리얼  >  프런트 엔드에서 WordPress 게시물 목록에 대한 사용자 정의 지시문 생성

프런트 엔드에서 WordPress 게시물 목록에 대한 사용자 정의 지시문 생성

王林
王林원래의
2023-08-30 08:13:13611검색

重写后的标题为:Creating a Custom Directive for WordPress Post Listing on the Front End

이 시리즈의 이전 부분에서는 AngularJS 애플리케이션을 부트스트랩하고, 다양한 보기에 대한 라우팅을 구성하고, 게시물, 사용자 및 카테고리에 대한 라우팅 관련 서비스를 구축했습니다. 이러한 서비스를 사용하여 이제 마침내 서버에서 데이터를 가져와 프런트 엔드를 구동할 수 있게 되었습니다.

이 시리즈에서는 게시물 목록 기능을 위한 사용자 정의 AngularJS 지시문을 작성하는 작업을 진행합니다. 이 시리즈의 현재 부분에서는 다음을 수행합니다.

  • AngularJS 지시어 소개 및 이를 만들어야 하는 이유
  • 게시물 목록 기능 계획 지침 및 필수 매개변수

  • 게시물 목록에 대한 사용자 정의 AngularJS 지시문 및 해당 템플릿 만들기

먼저 AngularJS 지시어와 이것이 필요한 이유를 소개하겠습니다.

AngularJS 지시어 소개

AngularJS의 지시문은 HTML 요소의 동작을 수정하고 반복 가능한 코드 블록을 재사용하는 방법입니다. HTML 요소와 해당 하위 요소의 구조를 수정하는 데 사용할 수 있으므로 사용자 정의 UI 위젯을 도입하는 완벽한 방법입니다.

이 시리즈의 첫 번째 부분에서 와이어프레임을 분석하는 동안 게시물 목록 기능이 다음 세 가지 보기에서 사용된다는 사실을 발견했습니다.

  1. 게시 목록
  2. 작가 소개

  3. 카테고리 게시물 목록

따라서 이 세 페이지에 게시물을 나열하는 별도의 함수를 작성하는 대신 이 시리즈의 앞부분에서 만든 서비스를 사용하여 게시물을 검색하는 비즈니스 논리가 포함된 사용자 정의 AngularJS 지시문을 만들 수 있습니다. 비즈니스 로직 외에도 이 지시어에는 특정 보기에 게시물을 나열하기 위한 렌더링 로직도 포함됩니다. 또한 이 지시문에는 특정 조건에 따라 게시물 페이지 매김 및 게시물 검색 기능이 정의되어 있습니다.

그래서 게시물 목록 기능에 대한 사용자 정의 AngularJS 지시문을 만들면 한 곳에서 기능을 정의할 수 있으므로 나중에 세 인스턴스 모두에서 코드를 변경하지 않고도 이 기능을 더 쉽게 확장하거나 수정할 수 있습니다. 그것.

이제 게시물 목록 기능에 대한 사용자 정의 지시어 작성을 시작해 보겠습니다.

게시물 목록 계획을 위한 맞춤 AngularJS 지시어

게시물 목록 기능 지시문을 작성하기 위한 코드 작성을 시작하기 전에 지시문에 필요한 기능을 분석해 보겠습니다.

가장 기본적인 수준에서는 게시물 목록, 작성자 프로필, 카테고리 페이지 보기에 사용할 수 있는 지시문이 필요합니다. 이는 HTML에 배치된 사용자 정의 UI 위젯(또는 DOM 태그)을 생성하고 AngularJS가 지시문의 특정 인스턴스에 대해 제공하는 옵션을 기반으로 나머지를 처리한다는 것을 의미합니다.

그러므로 다음 태그로 식별되는 사용자 정의 UI 위젯을 생성하겠습니다.

으아아아

하지만 이 지시문도 유연해야 합니다. 즉, 매개변수를 입력으로 받아 그에 따라 행동해야 합니다. 특정 사용자에게 속한 게시물만 표시하려는 사용자 프로필 페이지나 해당 카테고리에 속한 게시물이 나열되는 카테고리 페이지를 생각해 보세요. 이러한 매개변수는 두 가지 방법으로 제공될 수 있습니다.

  1. URL의 매개변수
  2. 명령어를 속성 값으로 직접 사용

URL에 매개변수를 제공하는 것은 우리가 이미 익숙하기 때문에 API에 기본적으로 제공되는 것 같습니다. 따라서 사용자는 다음을 통해 특정 사용자에게 속한 일련의 게시물을 검색할 수 있습니다.

으아아아

위 기능은 AngularJS에서 제공하는 $routeParams서비스를 통해 구현할 수 있습니다. 여기에서 사용자가 URL에 제공한 매개변수에 액세스할 수 있습니다. 우리는 이 시리즈의 이전 부분에서 경로를 등록할 때 이미 살펴보았습니다.

지시문에 매개변수를 속성 값으로 직접 제공하는 경우 다음과 같이 사용할 수 있습니다.

으아아아

위 스니펫에 있는 post-args 属性采用参数来检索一组特定的帖子,目前它采用作者 ID。此属性可以采用任意数量的参数来检索 /wp/v2/posts 경로 지원 게시물입니다. 따라서 ID가 1이고 카테고리 ID가 10인 사용자가 작성한 게시물 집합을 검색하려면 다음과 같이 할 수 있습니다.

으아아아

위 코드의 filter[cat] 매개변수는 특정 카테고리에 속하는 게시물 집합을 검색하는 데 사용됩니다.

페이지네이션은 게시물 목록 페이지 이용시 기본 기능이기도 합니다. 이 지시어는 페이지 매기기 이후를 처리하며, 이 함수는 응답 본문과 함께 서버에서 반환한 X-WP-TotalX-WP-TotalPages 헤더 값에 따라 구동됩니다. 따라서 사용자는 이전 게시물 세트와 다음 게시물 세트 사이를 앞뒤로 탐색할 수 있습니다.

목록 게시를 위한 사용자 지정 지시문의 핵심을 결정했으므로 이제 코드 작성을 시작할 수 있는 꽤 탄탄한 기반이 생겼습니다.

게시물 목록에 대한 맞춤 지시어 작성

게시물 목록 기능 구축 지침은 두 단계로 구성됩니다.

  1. 创建用于检索帖子和处理其他内容的业务逻辑。
  2. 为这些帖子创建一个渲染视图以显示在页面上。

我们的自定义指令的业务逻辑将在指令声明中处理。为了在 DOM 上呈现数据,我们将创建一个用于列出帖子的自定义模板。让我们从指令声明开始。

指令声明

AngularJS 中的指令可以使用以下语法为模块声明:

/**
 * Creating a custom directive for posts listing
 */
quiescentApp.directive( 'postListing', [function() {
    return {

    };
}] );

在这里,我们使用模块中可用的 .directive() 方法在模块上声明指令。该方法将指令的名称作为第一个参数,并且该名称与元素标签的名称密切相关。由于我们希望 HTML 元素为 <post-listing></post-listing>,因此我们提供了标签名称的驼峰式表示形式。您可以在官方文档中了解有关 AngularJS 执行的规范化过程以匹配指令名称的更多信息。

我们在上面的代码中使用的用于声明指令的符号称为安全样式的依赖注入。在这种表示法中,我们提供了一个依赖项数组作为指令所需的第二个参数。目前,我们尚未为自定义指令定义任何依赖项。但由于我们需要 Posts 服务来检索帖子(我们在本系列的上一部分中创建的)以及本机 AngularJS 的 $routeParams $location服务用于访问URL参数和当前路径,我们定义如下:

/**
 * Creating a custom directive for posts listing
 */
quiescentApp.directive( 'postListing', ['$routeParams', '$location', 'Posts', function( $routeParams, $location, Posts ) {
    return {
        restrict: 'E',
        scope: {
            postArgs: '='
        },
        link: function( $scope, $elem, $attr ) {
        
        }
    };
}] );

然后,这些依赖项可供定义为数组最后一个元素的函数使用。该函数返回一个包含指令定义的对象。目前,我们在指令定义对象中有两个属性,即 restrictlink

restrict 选项定义了我们在代码中使用指令的方式,该选项可以有四个可能的值:

  1. A:用于将指令用作现有 HTML 元素的属性。
  2. E:用于使用指令作为元素名称。

  3. C:用于使用指令作为类名。

  4. M:用于将该指令用作 HTML 注释。

restrict 选项也可以接受上述四个值的任意组合。

由于我们希望指令成为新元素 <post-listing></post-listing>,因此我们将限制选项设置为 E。如果我们要使用预先存在的 HTML 元素上的属性来定义指令,那么我们可以将此选项设置为 A。在这种情况下,我们可以使用 在 HTML 代码中定义该指令。

第二个 <code class="inline">scope 属性用于修改指令的范围。默认情况下, <code class="inline">scope 属性的值为 false,这意味着指令的范围与其父级的范围相同。当我们向它传递一个对象时,会为该指令创建一个隔离的范围,并且需要由其父级传递给该指令的任何数据都通过 HTML 属性传递。这就是我们在代码中所做的,我们使用的属性是 post-args,它被标准化为 postArgs

p>

<code class="inline">scope 对象中的 postArgs 属性可以接受以下三个值中的任意一个:

  1. =:表示传递给属性的值将被视为对象。
  2. @:这意味着传递到属性的值将被视为纯字符串。

  3. &:表示传递给属性的值将被视为函数。

由于我们选择使用 = 值,因此传递到 post-args 属性的任何值都将被视为 JSON 对象,我们可以使用该对象作为检索帖子的参数。

第三个属性 link 用于定义一个函数,该函数用于操作 DOM 并定义该指令所需的 API 和函数。该函数是处理指令所有逻辑的地方。

link 函数接受作用域对象、指令的 HTML 元素以及指令的 HTML 元素上定义的属性的对象的参数。目前,我们分别为范围对象和 HTML 元素传递两个参数 $scope$elem

让我们在 $scope 属性上定义一些变量,我们将使用该变量在 DOM 上呈现帖子列表功能。

/**
 * Creating a custom directive for posts listing
 */
quiescentApp.directive( 'postListing', ['$routeParams', '$location', 'Posts', function( $routeParams, $location, Posts ) {
    return {
        restrict: 'E',
        scope: {
            postArgs: '='
        },
        link: function( $scope, $elem, $attr ) {
            // defining variables on the $scope object
            $scope.posts = [];
            $scope.postHeaders = {};
            $scope.currentPage = $routeParams.page ? Math.abs( $routeParams.page ) : 1;
            $scope.nextPage = null;
            $scope.previousPage = null;
            $scope.routeContext = $location.path();
        }
    };
}] );

因此,我们在 $scope 对象上定义了六个属性,我们可以在 DOM 中访问它们。这些属性是:

  1. $posts:保存服务器返回的 post 对象的数组。
  2. $postHeaders:用于保存服务器将与响应正文一起返回的标头的对象。我们将使用它们来处理导航。

  3. $currentPage:保存当前页码的整型变量。

  4. $previousPage:保存上一页页码的变量。

  5. $nextPage:保存下一页编号的变量。

  6. $routeContext:用于使用 $location 服务访问当前路径。

我们之前为 HTML 属性定义的 postArgs 属性已在指令内的 $scope 对象上可用。

现在我们准备使用 Posts 服务向服务器发出请求以检索帖子。但在此之前,我们必须考虑用户作为 URL 参数提供的参数以及 post-args 属性中提供的参数。为此,我们将创建一个函数,使用 $routeParams 服务来提取 URL 参数,并将它们与通过 post-args 属性提供的参数合并: p>

/**
 * Creating a custom directive for posts listing
 */
quiescentApp.directive( 'postListing', ['$routeParams', '$location', 'Posts', function( $routeParams, $location, Posts ) {
    return {
        restrict: 'E',
        scope: {
            postArgs: '='
        },
        link: function( $scope, $elem, $attr ) {
            // defining variables on the $scope object
            $scope.posts = [];
            $scope.postHeaders = {};
            $scope.currentPage = $routeParams.page ? Math.abs( $routeParams.page ) : 1;
            $scope.nextPage = null;
            $scope.previousPage = null;
            $scope.routeContext = $location.path();
            
            // preparing query arguments
            var prepareQueryArgs = function() {
                var tempParams = $routeParams;
                delete tempParams.id;
                return angular.merge( {}, $scope.postArgs, tempParams );
            };
        }
    };
}] );

上述代码中的 prepareQueryArgs() 方法使用 angular.merge() 方法,该方法扩展了 $scope。 postArgs 对象与 $routeParams 对象。但在合并这两个对象之前,它首先使用 delete 运算符从 $routeParams 对象中删除 id 属性。这是必要的,因为我们将在类别和用户视图上使用此指令,并且我们不希望类别和用户 ID 被错误地解释为帖子 ID。

准备好查询参数后,我们终于准备好调用服务器并检索帖子,我们使用 Posts.query() 方法来执行此操作,该方法采用两个参数:

  1. 包含用于进行查询的参数的对象。
  2. 查询完成后执行的回调函数。

因此,我们将使用 prepareQueryArgs() 函数为查询参数准备一个对象,并在回调函数中设置 上某些变量的值$scope 属性:

// make the request and query posts
Posts.query( prepareQueryArgs(), function( data, headers ) {
    $scope.posts = data;
    $scope.postHeaders = headers();
    $scope.previousPage = ( ( $scope.currentPage + 1 ) > $scope.postHeaders['x-wp-totalpages'] ) ? null : ( $scope.currentPage + 1 );
    $scope.nextPage = ( ( $scope.currentPage - 1 ) > 0 ) ? ( $scope.currentPage - 1 ) : null;
});

回调函数获取响应正文和响应标头的两个参数。这些分别由 dataheaders 参数表示。

headers 参数是一个函数,它返回一个包含服务器响应标头的对象。

剩下的代码非常不言自明,因为我们正在设置 $scope.posts 数组的值。为了设置 $scope.previousPage$scope.nextPage 变量的值,我们使用 x-wp-totalpages 属性postHeaders 对象。

现在我们准备使用指令的自定义模板在前端渲染这些数据。

为指令创建自定义模板

为了使我们的指令发挥作用,我们需要做的最后一件事是为帖子列表制作一个单独的模板并将其链接到指令。为此,我们需要修改指令声明并包含 templateUrl 属性,如下所示:

/**
 * Creating a custom directive for posts listing
 */
quiescentApp.directive( 'postListing', ['$routeParams', '$location', 'Posts', function( $routeParams, $location, Posts ) {
    return {
        restrict: 'E',
        scope: {
            postArgs: '='
        },
        templateUrl: 'views/directive-post-listing.html',
        link: function( $scope, $elem, $attr ) {
        
        }
    };
}] );

上面代码中的 templateUrl 属性引用了 views 目录中名为 directive-post-listing.html 的文件。因此,在 views 文件夹中创建此文件并粘贴以下 HTML 代码:

<!-- post listing starts -->
<article class="post-entry">
    <h2 class="post-title"><a href="post-single.html">Good design is a lot like clear thinking made visual.</a></h2>
    <figure class="post-thumbnail">
        <img src="img/img-712-348.jpg" alt="Featured Image">
    </figure>
    <p class="post-meta">
        By <a href="author.html">Bilal Shahid</a> in <a href="category.html">Quotes</a>
    </p>
    <div class="post-content">
        <p>Created days forth. Dominion. Subdue very hath spirit us sixth fish creepeth also. First meat one forth above. You'll Fill for. Can't evening one lights won't. Great of make firmament image. Life his beginning blessed lesser meat spirit blessed seas created green great beginning can't doesn't void moving. Subdue evening make spirit lesser greater all living green firmament winged saw tree one divide wherein divided shall dry very lesser saw, earth the. Light their the.</p>
    </div>
</article>
<!-- post listing ends -->


<!-- pagination links start -->
<div class="post-pagination">
    <a href="#" class="button">Older Posts</a>
    <a href="#" class="button">Newer Posts</a>
</div>		
<!-- pagination links end -->

这是非常基本的 HTML 代码,表示单个帖子条目和帖子分页。我已从 views/listing.html 文件中复制了它。我们将使用一些 AngularJS 指令,包括 ng-repeatng-hrefng-srcng -bind-html,显示当前驻留在指令的 $scope 属性中的数据。

将 HTML 代码修改为以下内容:

<!-- post listing starts -->
<article class="post-entry" ng-repeat="post in posts">
    <h2 class="post-title"><a ng-href="#/posts/{{post.slug}}">{{post.title.rendered}}</a></h2>
    <figure class="post-thumbnail" ng-show="post.quiescent_featured_image">
        <img ng-src="{{post.quiescent_featured_image}}" alt="Featured Image">
    </figure>
    <p class="post-meta">
        By <a ng-href="#/users/{{post.author}}">{{post.quiescent_author_name}}</a> 
        in <a ng-href="#/categories/{{category.term_id}}" ng-repeat="category in post.quiescent_categories">{{category.name}}{{$last ? '' : ', '}}</a>
    </p>
    <div class="post-content" ng-bind-html="post.excerpt.rendered"></div>
    </article>
<!-- post listing ends -->

上面的代码使用 ng-repeat 指令来迭代 $scope.posts 数组。指令声明中 $scope 对象上定义的任何属性都可以直接在模板中使用。因此,我们在模板中将 $scope.posts 数组直接引用为 posts

通过使用 ng-repeat 指令,我们确保 article.post-entry 容器将在 中的每个帖子中重复posts 数组,每个帖子在内循环中被称为 post 。这个 post 对象包含服务器返回的 JSON 格式的数据,包含帖子标题、帖子 ID、帖子内容和特色图像链接等属性,这是同伴添加的附加字段插件。

在下一步中,我们将帖子标题、帖子链接和特色图像链接等值替换为 post 对象中的属性。

对于分页,将之前的代码替换为以下代码:

<!-- pagination links start -->
<div class="post-pagination">
    <a ng-href="#{{routeContext}}?page={{nextPage}}" class="button" ng-class="{'disabled': !nextPage}">Newer Posts</a>
    <a ng-href="#{{routeContext}}?page={{previousPage}}" class="button" ng-class="{'disabled': !previousPage}">Older Posts</a>
</div>		
<!-- pagination links end -->

我们首先访问我们在指令声明中定义的 routeContext 属性,并使用 ?page= 参数作为后缀,并使用 nextPagepreviousPage 变量用于在帖子之间来回导航。我们还检查下一页或上一页链接是否不是 null,否则我们将 .disabled 类添加到 Zurb Foundation 提供的按钮。

现在我们已经完成了该指令,是时候对其进行测试了。我们通过在 HTML 中放置一个 &lt;post-listing&gt;&lt;/post-listing&gt; 标签来实现这一点,最好位于 <footer></footer> 的上方标签。这样做意味着帖子列表将出现在页脚上方。不要担心格式和样式,我们将在本系列的下一部分中处理它们。

这就是为帖子列表功能创建自定义 AngularJS 指令的过程。

接下来会发生什么?

在有关使用 WP REST API 和 AngularJS 创建前端的系列的当前部分中,我们为帖子列表功能构建了一个自定义 AngularJS 指令。该指令使用我们在本系列前面部分创建的 Posts 服务。该指令还以 HTML 属性和 URL 参数的形式获取用户输入。

在本系列的最后部分,我们将开始研究项目的最后一部分,即帖子、用户和类别的控制器及其各自的模板。

위 내용은 프런트 엔드에서 WordPress 게시물 목록에 대한 사용자 정의 지시문 생성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.