简体   繁体   中英

Trouble accessing JSON node generated by Umbraco custom grid editor

Background

I'm new to Umbraco, and am working on creating my first custom grid editor. I'm trying to use an Umbraco custom grid editor to populate a simple image carousel from our official web template. I want the user to be able to select one or more images and apply a text banner (with or without a URL).

Issue

I have the image selection working, but I don't think I'm doing it in the most efficient method. I'm getting the resulting JSON object from the @Model, and then doing @Model.node.node.node until I get to the image URL. This seems like it's pretty fragile, and if the JSON ever changes then my carousel will be broken.

Here's the editor's AngularJS HTML:

<div ng-controller="imageCarousel.carouselController">
    <div>
        <div ng-show="control.value.carousel == undefined || control.value.carousel == ''">
            <i class="icon icon-add blue"></i>
            <a href="#" ng-click="pickImage()" prevent-default="">
                Add
            </a>
        </div>

        <div ng-show="control.value.carousel">
            <i class="icon icon-delete red"></i>
            <a href="#" ng-click="removeImage()" prevent-default="">
                Remove
            </a>
        </div>
    </div>

    <br />

    <ul ng-repeat="item in control.value.carousel">
        <li>
            {{item.id}}<br />
            <img src="{{item.properties[0].value.src}}" />
        </li>
    </ul>
</div>

Here's what the controller looks like:

angular.module("umbraco").controller("imageCarousel.carouselController",
    function ($scope, dialogService) {

        // Initialize the carousel array of images if it isn't there already
        if (!$scope.control.value) {
            $scope.control.value = {
                carousel: []
            };
        }

        // Populate the carousel array of images from the multi picker
        $scope.pickImage = function () {
            dialogService.mediaPicker({
                multiPicker: true,
                callback: function (data) {
                    //need $scope.control.value to work in a grid
                    angular.forEach(data, function (value, key) {
                        $scope.control.value.carousel.push(value);
                    })
                }
            });
        };

        // Set the carousel array to empty for now (need to figure out how to delete individual images)
        $scope.removeImage = function () {
            $scope.control.value = {
                carousel: []
            };
        };

    });

Here's what the Razor renderer currently looks like:

inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>

<pre>@Model</pre>

<div class="carousel owl-carousel carousel-content">
    @{
        foreach (var tmp in Model.value.carousel.Children())
        {
            <div class="item">
                <img src="@tmp.properties[0].value.src" />
                <div class="content-container">
                    <div class="content">
                        <h2>Large Hero Content</h2>
                    </div>
                </div>
            </div>
        }
    }
</div>

Here's a dump of the @Model (for a single image):

{
  "value": {
    "carousel": [
      {
        "properties": [
          {
            "id": 34,
            "value": {
              "src": "/media/1005/7834611966_e5efa3e3b2_o.jpg",
              "focalPoint": {
                "left": 0.47666666666666668,
                "top": 0.22546972860125261
              }
            },
            "alias": "umbracoFile",
            "editor": "Umbraco.ImageCropper"
          },
          {
            "id": 35,
            "value": "962",
            "alias": "umbracoWidth",
            "editor": "Umbraco.NoEdit"
          },
          {
            "id": 36,
            "value": "768",
            "alias": "umbracoHeight",
            "editor": "Umbraco.NoEdit"
          },
          {
            "id": 37,
            "value": "871793",
            "alias": "umbracoBytes",
            "editor": "Umbraco.NoEdit"
          },
          {
            "id": 38,
            "value": "jpg",
            "alias": "umbracoExtension",
            "editor": "Umbraco.NoEdit"
          },
          {
            "id": 41,
            "value": "",
            "alias": "linkText",
            "editor": "Umbraco.Textbox"
          },
          {
            "id": 40,
            "value": "",
            "alias": "linkTitle",
            "editor": "Umbraco.Textbox"
          },
          {
            "id": 39,
            "value": "",
            "alias": "linkURL",
            "editor": "Umbraco.Textbox"
          }
        ],
        "updateDate": "2017-02-15 11:53:06",
        "createDate": "2017-02-15 11:53:06",
        "published": false,
        "hasPublishedVersion": false,
        "owner": {
          "id": 0,
          "name": "xxx"
        },
        "updater": null,
        "contentTypeAlias": "bannerImage",
        "sortOrder": 4,
        "name": "7834611966_e5efa3e3b2_o.jpg",
        "id": 1088,
        "icon": "icon-slideshow color-orange",
        "trashed": false,
        "key": "fd1e3251-1597-4997-b795-f5c08c301519",
        "parentId": 1082,
        "alias": null,
        "path": "-1,1082,1088",
        "metaData": {},
        "isFolder": false,
        "thumbnail": "/media/1005/7834611966_e5efa3e3b2_o.jpg?width=500&mode=max&animationprocessmode=first",
        "image": "/media/1005/7834611966_e5efa3e3b2_o.jpg",
        "originalWidth": 962,
        "originalHeight": 768,
        "style": {
          "width": "173px",
          "height": "138px",
          "margin-right": "5px",
          "margin-bottom": "5px"
        },
        "thumbStyle": {
          "background-image": "url('/media/1005/7834611966_e5efa3e3b2_o.jpg?width=500&mode=max&animationprocessmode=first')",
          "background-repeat": "no-repeat",
          "background-position": "center",
          "background-size": "173px 138px"
        },
        "cssclass": "selected"
      }
    ]
  },
  "editor": {
    "name": "Image Carousel",
    "alias": "grid.imageCarousel",
    "view": "/App_Plugins/ImageCarousel/imageCarousel.html",
    "render": "/App_Plugins/ImageCarousel/imageCarouselRenderer.cshtml",
    "icon": "icon-layout",
    "config": {}
  },
  "active": true
}

Question

Are there any built-in functions that I can use instead of the @tmp.properties[0].value.src section I have? Setting the image picker to "single" breaks that node reference.

I still need to apply a title/URL to each image, and I don't think I'll be able to do that with a multi-image-picker. You can see the "LARGE HERO CONTENT" reference, and that's where the editable text (with optional URL applied) will need to go.

Any help would be greatly appreciated, thanks!

Nobody commented, but I wanted to list an answer just in case it helps someone. As I expected, I was just being overly complex (and, of course, dumb). The way you access Umbraco properties is through "mediaItem = Umbraco.Media(id)", then "linkText = @mediaItem.GetPropertyValue("linkText)".

Here's what the final (working) renderer looks like:

@inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>

<div class="carousel owl-carousel carousel-content">
    @{
        foreach (var tmp in Model.value.carousel.Children())
        {
            <div class="item">
                @{
                    var id = @tmp.id.ToString();
                    var mediaItem = Umbraco.Media(id);
                    var linkText = @mediaItem.GetPropertyValue("linkText");
                    var linkUrl = @mediaItem.GetPropertyValue("linkUrl");
                    var linkTitle = @mediaItem.GetPropertyValue("linkTitle");
                }

                <img src="@mediaItem.url" />

                <div class="content-container">
                    <div class="content">
                        @if (!string.IsNullOrWhiteSpace(linkText))
                        {
                            <h2>@linkText</h2>
                        }

                        @if (!string.IsNullOrWhiteSpace(linkUrl))
                        {
                            <a class="btn btn-primary backdrop" href="@linkUrl">@linkTitle</a>
                        }
                    </div>
                </div>
            </div>
        }
    }
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM